MySQL主从复制包括异步模式、半同步模式、GTID模式以及多源复制模式,本篇文章重点讲解一下mysql的半同步模式。
一,为什么要使用半同步复制?
mysql复制默认是异步复制,Mysql Master Server将自己的Binary Log通过复制线程传输出去以后,Mysql Master Sever就自动返回数据给客户端,但并不知道Slave是否或何时已经接收且已处理,因此存在一定的概率备库与主库的数据是不对等的。在异步复制的机制的情况下,如果Master宕机,事务在Master上已提交,但很可能这些事务没有传到任何的Slave上。假设有Master->Salve故障转移的机制,此时Slave也可能会丢失事务。有些情况下需要保持主备库的强一致性,此时启用MySQL的半同步复制特性则是非常完美的。semi_sync_replication是google为mysql开发的一个基于半同步的补丁,从mysql5.5之后,mysql为了保证主从库数据一致性,引进了semi-sync功能。
在半同步复制的架构下,当master在将自己binlog发给slave上的时候,要确保slave已经接受到了这个二进制日志以后,才会返回数据给客户端。对比两种架构:异步复制对于用户来说,可以确保得到快速的响应结构,但是不能确保二进制日志确实到达了slave上;半同步复制对于客户的请求响应稍微慢点,但是他可以保证二进制日志的完整性。
半同步复制的概念:
1,当Slave主机连接到Master时,能够查看其是否处于半同步复制的机制。
2,当Master上开启半同步复制的功能时,至少应该有一个Slave开启其功能。此时,一个线程在Master上提交事务将受到阻塞,直到得知一个已开启半同步复制功能的Slave已收到此事务的所有事件,或等待超时。
3,当一个事务的事件都已写入其relay-log中且已刷新到磁盘上,Slave才会告知已收到。在 Master 实例上,有一个专门的线程(ack_receiver)接收备库的响应消息,并以通知机制告知主库备库已经接收的日志,可以继续执行。
4,如果等待超时,也就是Master没被告知已收到,此时Master会自动转换为异步复制的机制。当至少一个半同步的Slave赶上了,Master与其Slave自动转换为半同步复制的机制。
5,半同步复制的功能要在Master,Slave都开启,半同步复制才会起作用;否则,只开启一边,它依然为异步复制。
6,半同步特性的出现,就是为了保证在任何时刻主备数据一致的问题。相对于异步复制,半同步复制要求执行的每一个事务,都要求至少有一个备库成功接收后,才返回给用户。
配置主节点:
1.mysql>installpluginrpl_semi_sync_mastersoname;2.QueryOK,0rowsaffected(0.07sec)3.4.mysql>showglobalvariableslike;5.+------------------------------------+--------------+6.|Variable_name|Value|7.+------------------------------------+--------------+8.|rpl_semi_sync_master_enabled|OFF|9.|rpl_semi_sync_master_timeout|10000|10.|rpl_semi_sync_master_trace_level|32|11.|rpl_semi_sync_master_wait_no_slave|ON|12.|rpl_semi_sync_master_wait_point|AFTER_COMMIT|13.+------------------------------------+--------------+14.5rowsinset(0.00sec)15.16.mysql>setglobalrpl_semi_sync_master_enabled=on;17.QueryOK,0rowsaffected(0.02sec)18.19.mysql>setglobalrpl_semi_sync_master_timeout=2000;20.QueryOK,0rowsaffected(0.00sec)21.22.mysql>showglobalvariableslike;23.+------------------------------------+--------------+24.|Variable_name|Value|25.+------------------------------------+--------------+26.|rpl_semi_sync_master_enabled|ON|27.|rpl_semi_sync_master_timeout|2000|28.|rpl_semi_sync_master_trace_level|32|29.|rpl_semi_sync_master_wait_no_slave|ON|30.|rpl_semi_sync_master_wait_point|AFTER_COMMIT|31.+------------------------------------+--------------+32.5rowsinset(0.00sec)33.rpl_semi_sync_master_enabled是控制Master是否开启半同步,开启或不开启,将其设置为ON或OFF(1or0).rpl_semi_sync_master_timeout是控制Master等待多长时间被告知Slave已收到,也就是所谓的超时时间。rpl_semi_sync_slave_enabled是控制Slave是否开启半同步,开启或不开启,将其设置为ON或OFF(1or0)。
监控半同步复制的状态变量(几个常用的):
Rpl_semi_sync_master_clients:查看有多少个开启半同步复制的插件的SlaveRpl_semi_sync_master_status:查看在Master上半同步复制是否正在运行,其值为ON时,说明Master已启用半同步且已被告知有Slave收到;其值为OFF时,说明Master没启用半同步或是没被告知,由于timeout等原因。Rpl_semi_sync_master_no_tx:查看有多少事务没有用半同步复制的机制进行复制。Rpl_semi_sync_master_yes_tx:查看有多少事务是通过半同步复制机制成功复制。Rpl_semi_sync_slave_status:查看Slave上半同步复制是否正常运行,其值为ON时,说明Slave正通过半同步复制且SlaveI/O正在运行;为OFF时,反之。
使用相同步骤配置从节点,完成后需要重启io_thread,不重启当执行时会超时,超时后则自动降为异步:
1.MariaDB[mydb]>installpluginrpl_semi_sync_mastersoname;2.MariaDB[mydb]>setglobalrpl_semi_sync_master_enabled=on;3.4.MariaDB[mydb]>stopslaveio_thread;5.QueryOK,0rowsaffected(0.01sec)6.7.MariaDB[mydb]>startslaveio_thread;8.QueryOK,0rowsaffected(0.00sec)9.10.mysql>showglobalstatuslike;11.+--------------------------------------------+-------+12.|Variable_name|Value|13.+--------------------------------------------+-------+14.|Rpl_semi_sync_master_clients|0|15.|Rpl_semi_sync_master_net_avg_wait_time|0|16.|Rpl_semi_sync_master_net_wait_time|0|17.|Rpl_semi_sync_master_net_waits|0|18.|Rpl_semi_sync_master_no_times|1|19.|Rpl_semi_sync_master_no_tx|3|20.|Rpl_semi_sync_master_status|OFF|21.|Rpl_semi_sync_master_timefunc_failures|0|22.|Rpl_semi_sync_master_tx_avg_wait_time|0|23.|Rpl_semi_sync_master_tx_wait_time|0|24.|Rpl_semi_sync_master_tx_waits|0|25.|Rpl_semi_sync_master_wait_pos_backtraverse|0|26.|Rpl_semi_sync_master_wait_sessions|0|27.|Rpl_semi_sync_master_yes_tx|0|28.+--------------------------------------------+-------+29.14rowsinset(0.00sec)
然后自行验证吧!
总结:使用半同步复制机制,性能也许会受到影响,但其主要是为了维持数据完整性,安全性的的一个策略,虽会损失一点性能,但还是值得的。
MySQL数据库表锁定的几种方法实现
如果两个程序都向表中写数据显然会造成很大的麻烦,甚至会有意外情况发生。 如果表正由一个程序写入,同时进行读取的另一个程序也会产生混乱的结果。 锁定表的方法防止客户机的请求互相干扰或者服务器与维护程序相互干扰的方法主要有多种。 如果你关闭数据库,就可以保证服务器和myisamchk和isamchk之间没有交互作用。 但是停止服务器的运行并不是一个好注意,因为这样做会使得没有故障的数据库和表也不可用。 本节主要讨论的过程,是避免服务器和myisamchk或isamchk之间的交互作用。 实现这种功能的方法是对表进行锁定。 服务器由两种表的锁定方法:1.内部锁定内部锁定可以避免客户机的请求相互干扰——例如,避免客户机的SELECT查询被另一个客户机的UPDATE查询所干扰。 也可以利用内部锁定机制防止服务器在利用myisamchk或isamchk检查或修复表时对表的访问。 语法:锁定表:LOCK TABLES tbl_name {READ | WRITE},[ tbl_name {READ | WRITE},…]解锁表:UNLOCK TABLESLOCK TABLES为当前线程锁定表。 UNLOCK TABLES释放被当前线程持有的任何锁。 当线程发出另外一个LOCK TABLES时,或当服务器的连接被关闭时,当前线程锁定的所有表自动被解锁。 如果一个线程获得在一个表上的一个READ锁,该线程(和所有其他线程)只能从表中读。 如果一个线程获得一个表上的一个WRITE锁,那么只有持锁的线程READ或WRITE表,其他线程被阻止。 每个线程等待(没有超时)直到它获得它请求的所有锁。 WRITE锁通常比READ锁有更高的优先级,以确保更改尽快被处理。 这意味着,如果一个线程获得READ锁,并且然后另外一个线程请求一个WRITE锁, 随后的READ锁请求将等待直到WRITE线程得到了锁并且释放了它。 显然对于检查,你只需要获得读锁。 再者钟情跨下,只能读取表,但不能修改它,因此他也允许其它客户机读取表。 对于修复,你必须获得些所以防止任何客户机在你对表进行操作时修改它。 2.外部锁定服务器还可以使用外部锁定(文件级锁)来防止其它程序在服务器使用表时修改文件。 通常,在表的检查操作中服务器将外部锁定与myisamchk或isamchk作合使用。 但是,外部锁定在某些系统中是禁用的,因为他不能可靠的进行工作。 对运行myisamchk或isamchk所选择的过程取决于服务器是否能使用外部锁定。 如果不使用,则必修使用内部锁定协议。 如果服务器用--skip-locking选项运行,则外部锁定禁用。 该选项在某些系统中是缺省的,如Linux。 可以通过运行mysqladmin variables命令确定服务器是否能够使用外部锁定。 检查skip_locking变量的值并按以下方法进行:◆如果skip_locking为off,则外部锁定有效您可以继续并运行人和一个实用程序来检查表。 服务器和实用程序将合作对表进行访问。 但是,运行任何一个实用程序之前,应该使用mysqladmin flush-tables。 为了修复表,应该使用表的修复锁定协议。 ◆如果skip_locaking为on,则禁用外部锁定,所以在myisamchk或isamchk检查修复表示服务器并不知道,最好关闭服务器。 如果坚持是服务器保持开启状态,月确保在您使用此表示没有客户机来访问它。
论坛进不了怎么办?
问题分析:出现这个错误一般情况下是因为下面两个原因:1、MySQL 服务器没有开启。 2、MySQL 服务器开启了,但不能找到 socket 文件。 解决方法:1、虚拟主机用户,请联系空间商确认数据库是否正常启动,并跟空间商确认 MySQL 的 socket 文件启动地址,可以尝试在 论坛根目录下的配置文件 中的 $dbhost 的值改为 $dbname = localhost:/tmp/‘,(这里假设 MySQL 的启动地址是 /tmp/,具体的启动地址依据空间商提供的启动地址而定)。 2、独立主机用户,请检查一下 MySQL 服务是否已经开启,没有开启,请启动 MySQL 服务;如果已经开启并且是 Linux 系统,请检查一下 MySQL 的 socket 路径,然后打开 找到$dbhost = localhost; 在 localhost 后面加冒号‘:’和 MySQL 的 socket路径。 比如 MySQL 服务器为 localhostMySQL 的 socket路径为 /tmp/那么就改成如下:$dbhost = localhost:/temp/;
哪位大哥谁帮我写一下这个sql语句 谢谢了 急!!

-- 所有系统select GROUP_CONCAT() as str from au;-- s1 不能写死select s1 as 系统, au.`user` as 用户 from au where POSITION(s1 IN )UNION ALLselect s2, au.`user` from au where POSITION(s2 IN )create procedure pro()BEGINdeclare i INT;set i = 0;while i<5 DO-- insert into f(fid, fname) values(i, i);select s1 as 系统, au.`user` as 用户 from au where POSITION(s1 IN )UNION ALLselect s2, au.`user` from au where POSITION(s2 IN );set i=i+1;end while;end;call pro();-- mysql 分割函数create function f_split(@str varchar(2000),@split varchar(2)) returns @t table(col varchar(20)) as begin while(charindex(@split,@str)<>0) begin insert @t(col) values (substring(@str,1,charindex(@split,@c)-1)) set @str = stuff(@str,1,charindex(@split,@str),) end insert @t(col) values (@str) return end slect role,wm_concat(user) from (SELECT role,user FROM table1 where role like %s1% union allSELECT role,user FROM table1 where role like %s1%union allSELECT role,user FROM table1 where role like %s1% )group by GROUP BY role-- DemoCREATE TABLE `lee` (`id` int(10) NOT NULL AUTO_INCREMENT,`name` char(20) DEFAULT NULL,`birthday` datetime DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8insert into lee(name,birthday) values (sam,1990-01-01);insert into lee(name,birthday) values (lee,1980-01-01);insert into lee(name,birthday) values (john,1985-01-01);select name, case when birthday<1981 then oldwhen birthday>1988 then yongelse ok END YORNfrom lee;
发表评论