ProxySQL配置详解及读写分离(+GTID)等功能说明(完整篇)散尽浮华

ProxySQL是灵活强大的MySQL代理层,是一个能实实在在用在生产环境的MySQL中间件,可以实现读写分离,支持Query路由功能,支持动态指定某个SQL进行cache,支持动态加载配置、故障切换和一些SQL的过滤功能。还有一些同类产品比如DBproxy、MyCAT、OneProxy等。但经过反复对比和测试之后,还是觉得ProxySQL是一款性能不谙,靠谱稳定的MySQL中间件产品!

ProxySQL的亮点所在

-几乎所有的配置均可在线更改(其配置数据基于SQLite存储),无需重启proxysql-基于正则和client_addr的强大和灵活的路由规则-详细的状态统计,统计结果和pt-query-digest对慢日志的分析结果类似,相当于有了统一的查看sql性能和sql语句统计的入口(DesignedbyaDBAforDBAs)-自动重连和重新执行机制(auto-reconnectandautomaticre-executionofqueriesusingit’sConnectionsPool):若一个请求在链接或执行过程中意外中断,proxysql会根据其内部机制重新执行该操作-querycache功能:比mysql自带QC更灵活,可在mysql_query_rules表中依据digest,match_pattern,client_addr等维度控制哪类语句可以缓存-支持连接池(connectionpool)并且支持multiplexing,区别于atlas之流的连接池实现。

ProxySQL的特点

ProxySQL是一个高性能的MySQL中间件,拥有强大的规则引擎。具有以下特性:-连接池,而且是multiplexing;-主机和用户的最大连接数限制;-自动下线后端DB;-延迟超过阀值-ping延迟超过阀值-网络不通或宕机-强大的规则路由引擎;-实现读写分离-查询重写-sql流量镜像-支持preparedstatement;-支持QueryCache;-支持负载均衡,与gelera结合自动failover;-将所有配置保存写入到SQLit表中。-支持动态加载配置,即一般可以在线修改配置,但有少部分参数还是需要重启来生效。-支持querycache。-支持对query的路由,可以针对某个语句进行分配去哪个实例执行。-不支持分表,可以分库,但是利用规则配置实现分表。

如上可知,ProxySQL集合了很多优秀特性于一身,那么它的缺点呢就是项目不够成熟,好在官方网站一直在及时更新,并且受到Percona官方的支持。

ProxySQL多层管理配置设计(有三层配置)

-runtime:运行中使用的配置文件-memory:提供用户动态修改配置文件-disk:将修改的配置保存到磁盘SQLit表中(即:proxysql.db)-config:一般不使用它(即:proxysql.cnf)

ProxySQL运行机制草图如下:ProxySQL有一个完备的配置系统,配置ProxySQL是基于sql命令的方式完成的。ProxySQL支持配置修改之后的在线保存、应用,不需要重启即可生效。整个配置系统分三层设计。整个配置系统分为三层,如下图所示:

ProxySQL配置系统分为三层的目的:1)自动更新;2)尽可能的不重启proxysql就可以修改配置;3)方便回滚错误配置;

简单说就是配置proxysql分为三个级别,RUNTIME是即时生效的,MEMORY是保存在内存中但并不立即生效的,DISK|CONFIGFILE是持久化或写在配置文件中的。

这三个级别的配置文件互不干扰,在某个层级修改了配置文件,想要加载或保存到另一个层级,需要额外的LOAD或SAVE操作:"LOADxx_configFROMxx_level|LOADxx_configTOxx_level|SAVExx_configTOxx_level|SAVExx_configFROMxx_level",达到加载配置或者持久化配置的目的。这三层中每层的功能与含义如下:-RUNTIME层代表的是ProxySQL当前生效的配置,包括global_variables,mysql_servers,mysql_users,mysql_query_rules。无法直接修改这里的配置,必须要从下一层load进来。该层级的配置时在proxysql管理库(sqlite)的main库中以runtime_开头的表,这些表的数据库无法直接修改,只能从其他层级加载;该层代表的是ProxySQL当前生效的正在使用的配置,包括global_variables,mysql_servers,mysql_users,mysql_query_rules表。无法直接修改这里的配置,必须要从下一层load进来。也就是说RUNTIME这个顶级层,是proxysql运行过程中实际使用的那一份配置,这一份配置会直接影响到生产环境的,所以要将配置加载进RUNTIME层时需要三思而行。

-MEMORY层是平时在mysql命令行修改的main里头配置,可以认为是SQLite数据库在内存的镜像。该层级的配置在main库中以mysql_开头的表以及global_variables表,这些表的数据可以直接修改;用户可以通过MySQL客户端连接到此接口(admin接口),然后可以在mysql命令行查询不同的表和数据库,并修改各种配置,可以认为是SQLite数据库在内存的镜像。也就是说MEMORY这个中间层,上面接着生产环境层RUNTIME,下面接着持久化层DISK和CONFIGFILE。MEMORY层是我们修改proxysql的唯一正常入口。一般来说在修改一个配置时,首先修改Memory层,确认无误后再接入RUNTIME层,最后持久化到DISK和CONFIGFILE层。也就是说memeory层里面的配置随便改,不影响生产,也不影响磁盘中保存的数据。通过admin接口可以修改mysql_servers、mysql_users、mysql_query_rules、global_variables等表的数据。

-DISK|CONFIGFILR层持久存储的那份配置,一般在$(DATADIR)/proxysql.db,在重启的时候会从硬盘里加载。/etc/proxysql.cnf文件只在第一次初始化的时候用到,完了后,如果要修改监听端口,还是需要在管理命令行里修改,再save到硬盘。该层级的配置在磁盘上的sqlite库或配置文件里。DISK/CONFIGFILE层表示持久存储的那份配置,持久层对应的磁盘文件是$(DATADIR)/proxysql.db,在重启ProxySQL的时候,会从proxysql.db文件中加载信息。而/etc/proxysql.cnf文件只在第一次初始化的时候使用,之后如果要修改配置,就需要在管理端口的SQL命令行里进行修改,然后再save到硬盘。也就是说DISK和CONFIGFILE这一层是持久化层,我们做的任何配置更改,如果不持久化下来,重启后,配置都将丢失。

需要注意1)ProxySQL每一个配置项在三层中都存在,但是这三层是互相独立的,也就是说proxysql可以同时拥有三份配置,每层都是独立的,可能三份配置都不一样,也可能三份都一样。2)RUNTIME层代表ProxySQL当前生效的正在使用的配置,无法直接修改这里的配置,必须要从下一层"load"进来。3)MEMORY这一层上面连接RUNTIME层,下面连接持久化层。在这层可以正常操作ProxySQL配置,随便修改,不会影响生产环境。修改一个配置一般都是先在MEMORY层完成,然后确认正常之后再加载到RUNTIME和持久化到磁盘上。4)DISK和CONFIGFILE层持久化配置信息,重启后内存中的配置信息会丢失,所以需要将配置信息保留在磁盘中。重启时,可以从磁盘快速加载回来。

ProxySQL配置文件的修改流程一般是:-启动时:先修改必要的CONFIGFILE配置,比如管理端口,然后启动;-其他配置:修改MEMORY中的表,然后加载到RUNTIME并持久化。

一般,修改的配置都是在memory层。可以load到runtime,使配置在不用重启proxysql的情况下也可以生效,也可以save到disk,将对配置的修改持久化!

需要修改配置时,直接操作的是MEMORAY,以下命令可用于加载或保存users(mysql_users):(序号对应上图“运行机制”草图)

[1]:LOADMYSQLUSERSTORUNTIME/LOADMYSQLUSERSFROMMEMORY#常用。将修改后的配置(在memory层)用到实际生产[2]:SAVEMYSQLUSERSTOMEMORY/SAVEMYSQLUSERSFROMRUNTIME#将生产配置拉一份到memory中[3]:LOADMYSQLUSERSTOMEMORY/LOADMYSQLUSERSFROMDISK#将磁盘中持久化的配置拉一份到memory中来[4]:SAVEMYSQLUSERSTODISK/SAVEMYSQLUSERSFROMMEMORY#常用。将memoery中的配置保存到磁盘中去[5]:LOADMYSQLUSERSFROMCONFIG#将配置文件中的配置加载到memeory中个人还是比较习惯用TO,记住往上层是LOAD,往下层是SAVE。以下命令加载或保存servers(mysql_servers):

[1]:LOADMYSQLSERVERSTORUNTIME#常用,让修改的配置生效[2]:SAVEMYSQLSERVERSTOMEMORY[3]:LOADMYSQLSERVERSTOMEMORY[4]:SAVEMYSQLSERVERSTODISK#常用,将修改的配置持久化[5]:LOADMYSQLSERVERSFROMCONFIG后面的使用方法也基本相同,一并列出。以下命令加载或保存queryrules(mysql_query_rules):

[1]:loadmysqlqueryrulestorun#常用[2]:savemysqlqueryrulestomem[3]:loadmysqlqueryrulestomem[4]:savemysqlqueryrulestodisk#常用[5]:loadmysqlqueryrulesfromconfig以下命令加载或保存mysqlvariables(global_variables):

[1]:loadmysqlvariablestoruntime[2]:savemysqlvariablestomemory[3]:loadmysqlvariablestomemory[4]:savemysqlvariablestodisk[5]:loadmysqlvariablesfromconfig以下命令加载或保存adminvariables(select*fromglobal_variableswherevariable_namelike'admin-%'):

[1]:loadadminvariablestoruntime[2]:saveadminvariablestomemory[3]:loadadminvariablestomemory[4]:saveadminvariablestodisk[5]:loadadminvariablesfromconfigProxySQL启动过程总结:当proxysql启动时,首先读取配置文件CONFIGFILE(/etc/proxysql.cnf),然后从该配置文件中获取datadir,datadir中配置的是sqlite的数据目录。如果该目录存在,且sqlite数据文件存在,那么正常启动,将sqlite中的配置项读进内存,并且加载进RUNTIME,用于初始化proxysql的运行。如果datadir目录下没有sqlite的数据文件,proxysql就会使用configfile中的配置来初始化proxysql,并且将这些配置保存至数据库。sqlite数据文件可以不存在,/etc/proxysql.cnf文件也可以为空,但/etc/proxysql.cnf配置文件必须存在,否则,proxysql无法启动。

一、ProxySQL安装(两种方式)

mysql_ifaces也就是说proxysql有一个admin接口专门来做配置,相当于一个mysqlshell可以通过sql来让配置实时生效。mysql_ifaces配置了允许连接proxysql的ip和port

表mysql_users

表mysql_replication_hostgroups

MySQL[(none)]>showcreatetablemysql_replication_hostgroups\G;***************************1.row***************************table:mysql_replication_hostgroupsCreateTable:CREATETABLEmysql_replication_hostgroups(writer_hostgroupINTCHECK(writer_hostgroup>=0)NOTNULLPRIMARYKEY,reader_hostgroupINTNOTNULLCHECK(reader_hostgroup<>writer_hostgroupANDreader_hostgroup>0),commentVARCHARNOTNULLDEFAULT'',UNIQUE(reader_hostgroup))1rowinset(0.001sec)ERROR:NoqueryspecifiedMySQL[(none)]>select*frommysql_replication_hostgroups;+------------------+------------------+---------+|writer_hostgroup|reader_hostgroup|comment|+------------------+------------------+---------+|10|20|1|+------------------+------------------+---------+1rowinset(0.000sec)定义hostgroup的主从关系。ProxySQLmonitor模块会监控HG后端所有servers的read_only变量,如果发现从库的read_only变为0、主库变为1,则认为角色互换了,自动改写mysql_servers表里面hostgroup关系,达到自动Failover效果。

表mysql_query_rulesmysql_query_rules是ProxySQL非常核心一个表,定义查询路由规则

以上都是匹配查询的规则,1.3.5版本使用的正则引擎只有RE2,1.4版本可以通过变量mysql-query_processor_regex设置RE2或者PCRE,且1.4开始默认是PCRE。推荐用match_digest。关于每条查询都会计算digest对性能的影响,计算querydigest确实会有性能损失,但是这却是proxysql里面非常重要的特性,主要是两点:-proxysql无法知道连接复用(multipexing)是否必须被自动禁用,比如连接里面有variables/tmptables/locktable等特殊命令,是不能复用的。-完整的查询去匹配正则的效率,一般没有参数化后的查询匹配效率高,因为有很长的字符串内容需要处理。再者,SELECT*FROMrandomtableWHEREcommentLIKE‘%INTOsbtest1%FROMsbtest2%’字符串里有类似这样的语句,很难排除误匹配。-negate_match_pattern:反向匹配,相当于对match_digest/match_pattern的匹配取反。-re_modifiers:修改正则匹配的参数,比如默认的:忽略大小写CASELESS、禁用GLOBAL.

proxysql对后端server健康检查

这里强烈推荐用第一种方式因为第一种是完全由我们控制的;而第二种假如我们误将读server的read_only属性设置为0,则proxysql会将其重新分配到写组,这绝对是不期望的。

ProxySQL下添加与修改配置

1.实验环境

4.1ProxySQL实现读写分离

向ProxySQL中添加MySQL节点

首先在后端master主数据节点上创建一个用于监控的用户名(只需在master上创建即可,因为会复制到slave上),这个用户名只需具有USAGE权限即可。如果还需要监控复制结构中slave是否严重延迟于master(这个俗语叫做"拖后腿",术语叫做"replicationlag"),则还需具备replicationclient权限。

必须注意:这只是实验,实际的路由规则绝不应该仅根据所谓的读、写操作进行分离,而是从各项指标中找出压力大、执行频繁的语句单独写规则、做缓存等等。和查询规则有关的表有两个:mysql_query_rules和mysql_query_rules_fast_routing,后者是前者的扩展表,1.4.7之后才支持该快速路由表。本案例只介绍第一个表。插入两个规则,目的是将select语句分离到hostgroup_id=20的读组,但由于select语句中有一个特殊语句SELECT...FORUPDATE它会申请写锁,所以应该路由到hostgroup_id=10的写组.

4.4scheduler打印proxysql状态到日志

[root@mysql-proxy~]#mkdir-p/opt/proxysql/log[root@mysql-proxy~]#vim/opt/proxysql/log/status.sh#!/bin/bashDATE=`date"+%Y-%m-%d%H:%M:%S"`echo"{\"dateTime\":\"$DATE\",\"status\":\"running\"}">>/opt/proxysql/log/status_log[root@mysql-proxy~]#chmod777/opt/proxysql/log/status.sh然后在proxysql插入一条scheduler(定义每分钟打印一次,即60000毫秒)[root@mysql-proxy~]#mysql-uadmin-padmin-h127.0.0.1-P6032........................MySQL[(none)]>insertintoscheduler(active,interval_ms,filename)values(1,60000,'/opt/proxysql/log/status.sh');QueryOK,1rowaffected(0.000sec)MySQL[(none)]>LOADSCHEDULERTORUNTIME;QueryOK,0rowsaffected(0.001sec)MySQL[(none)]>SAVESCHEDULERTODISK;QueryOK,0rowsaffected(0.105sec)然后查看日志就可以看到proxysql的运行结果了:[root@mysql-proxy~]#tail-f/opt/proxysql/log/status_log{"dateTime":"2019-02-1914:24:03","status":"running"}{"dateTime":"2019-02-1914:25:03","status":"running"}{"dateTime":"2019-02-1914:26:03","status":"running"}{"dateTime":"2019-02-1914:27:03","status":"running"}

THE END
1.以下声明中,错误的是?A.inta=0xFF;B.doublea=1.2e0.5;C...以下声明中,错误的是? A. int a=0xFF; B. double a=1.2e0.5; C. long a=2L; D. char a='\72';https://m.ppkao.com/wangke/daan/8f26a34acadc47f0baa8d8eef64f552e
2.以下哪个表述是错误的。()以下哪个表述是错误的。() 很多小伙伴都积极入坑,但并非那么容易上手,尤其对新手玩家不是很友好,攻略问答中常常会遇到以下哪个表述是错误的。()不知如何解决,为此小编给大家收集整理以下哪个表述是错误的。()解决办法,感兴趣的快来看看吧。 以下哪个表述是错误的。()...https://www.duote.com/tech/xxyxgl/315254.html
3.热能动力方案设计说明书中内容描述错误的是()。A.锅炉房及场区...热能动力方案设计说明书中内容描述错误的是()。 A.锅炉房及场区面积、换热站面积、位置及房高等要求 B.水源、水质、水压要求 C.节能、环保、消防及安全措施 D.热力管道布置方式及原理图示查看答案 如搜索结果不匹配,请 联系老师 获取答案 您可能会需要:...https://m.shangxueba.com/ask/3229989.html
4.(ACL)分为标准和扩展两种。下面关于ACL的描述中,错误的是(63).ACL规定使用通配符掩码来说明子网地址,通配符掩码就是子网掩码按位取反的结果。通配符掩码0.0.0.0表示ACL语句中的32位地址要求全部匹配,因而叫作主机掩码。例如:192.168.1.1 0.0.0.0表示主机192.168.1.1的IP地址,实际上路由器把这个地址转换为host 192.168.1.1,注意这里的关键字host。 通配符掩码255.255.255.255表示任意...http://www.rkpass.cn/tk_timu/7_92_63_xuanze.html
5.斑马ZebraS4M操作手册指示灯外观功能/说明 POWER(电源) 指示打印机电源已打开 ALERT(警报) 在错误或警报情况下,“警报”指示灯闪烁。 PAUSE(PAUSE按钮的一部分) 当打印机处于“暂停”模式下时,除非打印机进入“设置”模式并且下箭头活动,否则指示灯将闪烁。 FEED(FEED按钮的一部分) 在常规打印机操作过程中,指示打印机可以送入空白标签...http://www.chongshang.com.cn/manual/m_S4M.shtml
1.下列对假设检验的说明中错误的是()【单选题】以下有关数组的说明中,错误的是() A. 在过程中,不能用Private语句定义数组 B. 数组重新定维后,原有的数组元素内容将不予保留 C. 利用ReDim语句重新定维时,不得改变已经说明过的数组的数据类型 D. 根据数组说明的方式,可将数组分为动态数组和静态数组 查看完整题目与答案 【单选题】假设...https://www.shuashuati.com/ti/d0c9a807b2e94118bb9990df6b830b6f.html
2.python期末考试练习题库(含答案).docx()A、*B、&C、>=D、not答案:A66.(单选题,)关于Python字符编码,以下选项中描述错误的是A、chr(x)和ord(x)函数用于在单字符和Unicode编码值之间进行转换B、printchr(65)输出AC、print(ord('a'))输出97D、Python字符编码使用ASCII编码答案:D67.(单选题,)已知字典dic={'小欣':90,'小蕊':92,'小微':...https://m.renrendoc.com/paper/225753141.html
3.最全软件测试基础理论选择题(含答案)A、经过测试没有发现错误说明程序正确 B、测试的目标是为了证明程序没有错误 C、成功的测试是发现了迄今尚未发现的错误的测试 D、成功的测试是没有发现错误的测试 【答案】C 3、软件测试中白盒法是通过分析程序的( )来设计测试用例的。 A、应用范围 https://blog.csdn.net/maoxuexue/article/details/104515599
4.全国计算机等级考试四级软件测试工程师笔试训练8. 破坏性测试的任务是评测软件在承受超出其正常负荷N倍的情况下,错误出现时的状态和错误发生后的恢复能力。它的实施主要在 A) 系统层 B) 子系统层 C) **/指标层 D) 用户层 9. 程序代码检查过程中为检查说明、使用错误,通常需要借助一些引用表。以下不适用于做这种检查的引用表是 ...https://www.oh100.com/kaoshi/ncre4/tiku/378340.html
5.Solaris105/08发行说明NFSv4 域-在升级后,当您初启每个标记区域时,系统将提示您输入 NFSv4 域。要避免出现此提示,请在升级前在每个标记区域的/etc/default/nfs文件中添加正确的NFSMAPID_DOMAIN值。有关更多信息,请参见 CR 5110062。 Live Upgrade-以下两个错误会影响具有区域的 Solaris 系统的 Live Upgrade: ...https://docs.oracle.com/cd/E19253-01/820-4534/installbugs-113/index.html
6.2017公卫执业医师考试精选备考试题及答案7. 下列关于凋亡的叙述,哪项是错误的 A 常引发急性炎症反应 B 可发生于病毒性肝炎的肝细胞 C 与基因调控有关 D HE染色切片中可见到嗜酸性小体 E 不出现结构自溶 8. 下列哪种细胞再生能力最弱 A 心肌细胞 B 胃粘膜上皮细胞 C 肾小管上皮细胞 ...https://www.yjbys.com/edu/gongweizhiyeyishi/286996.html
7.专利审查指南如果上述内容又出现在译文中,审查员应当发出补正通知书,通知申请人改正译文中的错误。国际公布时对上述内容没有删除,并出现在译文中的,应当参照本指南第一部分第一章第7节的规定处理。 在国际阶段,国际申请说明书、权利要求书中包含有核苷酸和/或氨基酸序列,并且序列表是作为说明书单独部分提交的,在提交译文时,应当...http://www.iprtop.com/law/f_14/p_109/
8.2018年4月基金从业《基金法律法规》真题回顾基金从业B. 基金合同、招募说明书 C. 公司章程或者合伙协议 D. 基金主要投资方向和类别 正确答案:A 8 关于基金投资人风险承受能力调查和评价,以下说法错误的是() A. 销售机构应通过适当途径向投资人公开其调查和评价方法 B. 为避免重复采集,提高评估效率,销售机构无需对基金投资人重复进行调查 ...https://m.233.com/jjcy/jichu/zhenti/201804/23091033774.html
9.汽车内容推荐标准指南以上要求详细说明、举例,均可在上文中查阅。 若内容的推荐状态显示「懂车帝推荐」,未显示「懂车帝优质推荐」,则说明该内容大体上符合「懂车帝推荐」要求,未达标「懂车帝优质推荐」要求,若想进一步提升内容质量,获得更多懂车帝展现、分发机会,可对比「懂车帝优质推荐」五大要求,进行逐一优化提升。「懂车帝优质推荐」五大要求...https://www.dongchedi.com/article/7067080276073267748
10.AION2.修正了技能'精灵合体'在使用时移动速度增加数值显示错误的问题 3.修正了技能'抵抗之契约'与'精灵合体'技能配合使用的问题 4.修正了技能 ‘命令:愤怒之气势’ 在提示中技能效果说明错误的情况 5.将技能 ‘吸引’的初始习得等级由51级变更为26级 6.修复了技能 ‘灵魂之呼喊:人参’使用后,无法发动 ‘恶梦束缚...http://aion.sdo.com/newsContent.asp?id=241612&CategoryID=5892
11.说明书中写有对附图的说明但无附图怎么处理1、说明书中写有对附图的说明但无附图或者缺少部分附图的,按以下情形处理: (1)申请人应当在国务院专利行政部门指定的期限内补交附图或者声明取消对附图的说明; (2)申请人补交附图的,以向国务院专利行政部门提交或者邮寄附图之日为申请日;取消对附图的说明的,保留原申请日。 https://www.66law.cn/laws/1739040.aspx
12.就业与创业指导专刊2018年2期(总第123期)如果在辞职理由中这么写的话会给面试官留下不好的印象,因为他会觉得你一有不喜欢做的事情就立马辞职。面试官之所以会面试你是因为想要看看你进入公司以后能不能充分展示自己的才能,因此,你对工作的态度会成为他们重要的判断要素。 首先要说一下,简历里的辞职理由不需要写得太细。但是,还是有必要大致地说明一下是...https://www.czzy-edu.com/23/30/181/184/content_3999.html
13.锐捷认证客户端用户手册RG-Supplicant软件安装说明 一、安装过程 1、 运行安装程序,启动安装程序。出现如图1.1的安装界面。 图1.1 2、 在下拉列表中选择安装语言,以下以选择“中文”为例,说明如何安装;点击“下一步”,出现如图1.2界面。 图1.2 3、 按“下一步”,出现如图1.3界面。 https://www.hd-u.com/xdjy/info/1120/1265.htm
14.常见公司名称大全(免费简单大气)第1篇2023常见五金店顺口名字起名方法 第2篇给公司起名要避免的常见错误 第3篇公司起名的6中常见方法 第4篇品牌名称的常见类型及固有词命名的优势 第5篇公司起名常见问题 第6篇公司取名的常见问题 第7篇常见的公司起名方法大全,寓意大气的公司企业起名 第8篇常见的公司起名注意点大全,简单好听好读的公司名称 第9...https://www.1566.cn/gongsimingzi/37445.html
15.皮勇:论医疗人工智能的刑法问题医疗人工智能以高概率为决策标准,其诊断和治疗方案是否适应特定患者存在疑问,发生诊疗错误的可能性不仅客观存在,而且会保持一定比例。医师认识医疗人工智能的以上特点向患者说明中面临诸多困难。 第三,医疗人工智能应用中医师的注意义务和注意能力问题。在认定医疗事故罪中,必须确定医师是否具有注意能力和违反注意义务。医疗...https://www.legal-theory.org/?mod=info&act=view&id=26111