1.1 MySQL 5.7.17 二进制包 安装新特性
- 安装
tar xf mysql-5.7.17-linux-glibc2.5-x86_64.tar.gz
mv mysql-5.7.17-linux-glibc2.5-x86_64 /application/mysql-5.7.17
- 解压创建软链接
[root@db02 application]# ll
total 8
lrwxrwxrwx 1 root root 26 Nov 13 19:52 mysql -> /application/mysql-5.7.17/
drwxr-xr-x 14 mysql mysql 4096 Nov 11 12:37 mysql-5.6.36
drwxr-xr-x 10 mysql mysql 4096 Nov 13 19:26 mysql-5.7.17
[root@db02 application]#
- 授权
chown -R mysql.mysql /application/mysql-5.7.17
4.初始化
/application/mysql-5.7.17/bin/mysqld --initialize --user=mysql --basedir=/application/mysql-5.7.17 --datadir=/application/mysql-5.7.17/data
2017-11-13T11:26:36.962419Z 0 [Warning] TIMESTAMP with implicit DEFAULT value
is deprecated. Please use --explicit_defaults_for_timestamp server option (see
documentation for more details).
2017-11-13T11:26:36.962511Z 0 [Warning] 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
2017-11-13T11:26:36.962517Z 0 [Warning] 'NO_AUTO_CREATE_USER' sql mode was not set.
2017-11-13T11:26:39.814655Z 0 [Warning] InnoDB: New log files created, LSN=45790
2017-11-13T11:26:40.459732Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2017-11-13T11:26:40.706330Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 85055ea7-c865-11e7-b2df-000c29310c49.
2017-11-13T11:26:40.709986Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2017-11-13T11:26:40.711523Z 1 [Note] A temporary password is generated for root@localhost: i3fBr#tX0kkg #初始化的密码修改密码的时候需要填这个(5.7的新特性)
[root@db02 bin]# echo $?
0
[root@db02 bin]#
5.修改启动文件配置文件
cp
/application/mysql-5.7.17/support-files/mysql.server /etc/init.d/mysqld5.7
cp /application/mysql-5.7.17/support-files/my-default.cnf /etc/my.cnf5.7
sed 's#/usr/local#/application#g' /application/mysql-5.7.17/bin/mysqld_safe
/etc/init.d/mysqld -i
- 启动修改密码
/etc/init.d/mysqld start
[root@db02 bin]# ./mysqladmin -uroot -p password 123
Enter password: 输入i3fBr#tX0kkg
1.2 扩展二SQL层
select user,host form mysql.user
我们想看到的结果是什么?
二维表 表格
这些表存到到了 磁盘上了 MYD IBD
--------
1.必须明确告诉mysql 数据放在哪个文件的那些位置了?
2.我们又知道,真正和磁盘数据打交道的是存储引擎
3.也就意味着要去磁盘取到数据,必须明确告诉存储引擎 数据到底放在哪,以及怎么取。
4.数据的存储位置,以及取数据的方式,我们称之为“执行计划”
总结:我们取数据,要告诉存储引擎“执行计划”
执行计划就是存储引擎取数据的方法。
---------------
sql层的功能
1.将接收到SQL语句,解析成执行计划。
2.查询优化器----->选择最优的执行计划
3.查询缓存:缓存执行计划
4.附加功能:权限、语法检查、对象存在性
5.日志记录(二进制日志,只记录成功执行的)
1.3 复制延时
问题:
主服务器的错误操作会同步到从服务器,导致数据恢复比较麻烦。
解决方法:
采用复制延时,这样主服务器操作错误,从服务器由于延时复制可以在一段时间内避免应用错误操作,这样就可以及时恢复数据。
复制延时是在SQL线程的层面进行控制,不允许SQL线程实时的执行relay log中的操作。
目的:
² 防止用户在主人的错误。DBA可以将一个延迟的从属器恢复到灾难发生前的时间。
² 测试系统在出现滞后时的表现。例如,在一个应用程序中,一个滞后可能是由于从属设备的负载过重造成的。但是,生成这个负载级别可能很困难。延迟复制可以模拟延迟,而不必模拟负载。它也可以用来调试与滞后从属相关的条件。
² 检查数据库很久以前的样子,而不必重新加载备份。例如,如果延迟时间为一周,DBA需要在最后几天的开发之前查看数据库的外观,则可以检查延迟的从站。
如何设置:
stop slave;
change master to master_delay = 30; #单位是秒
start slave;
结果
mysql> show slave statusG
SQL_Delay: 30
SQL_Remaining_Delay: NULL
生产场景中一般延时3-6小时
SHOW SLAVE STATUS 有三个字段提供有关延迟的信息:
² SQL_Delay:一个非负整数,表示从站必须滞后主站的秒数。
² SQL_Remaining_Delay:什么时候 Slave_SQL_Running_State是Waiting until MASTER_DELAY seconds after master executed event,这个字段包含一个整数,表示延迟的剩余秒数。在其他时候,这个领域是NULL。
² Slave_SQL_Running_State:一个字符串,指示SQL线程的状态(类似于 Slave_IO_State)。该值与State显示的SQL线程的值相同SHOW PROCESSLIST。
注意:
当从属SQL线程在执行事件之前正在等待延迟时间时,将SHOW PROCESSLIST其State值显示为Waiting until MASTER_DELAY seconds after master executed event。
该relay-log.info文件现在包含延迟值,所以文件格式已经改变。特别是,文件的第一行现在指出文件中有多少行。如果将从属服务器降级到比MySQL 5.6旧的版本,旧的服务器将无法正确读取该文件。要解决这个问题,请在文本编辑器中修改文件以删除包含行数的起始行。
1.4 半同步复制
默认情况下,MySQL复制是异步的。主站将事件写入其二进制日志,但不知道是否或何时从站检索并处理它们。在异步复制的情况下,如果主服务器崩溃,它所提交的事务可能不会被传输给任何从服务器。因此,在这种情况下,从主服务器到从服务器的故障转移可能会导致故障转移到缺少相对于主服务器的事务的服务器。
特性:
² 注重安全,不注重性能
² 普通异步主从中从库的同步率是不可控的,总会有延时的
² 对于安全性要求比较高的应用场景,比如金融、运营商等不会使用普通异步主从架构。
² 为了让MySQL更加能够适用于高安全性的场景才有了半同步复制。
² 半同步基于dump线程和IO线程,省略了SQL线程读取写入的部分
半同步复制可用作异步复制的替代方法:
² 一个从机指示它连接到主机时是否具有半同步功能。
² 如果在主端启用了半同步复制,并且至少有一个半同步从端,则在完成提交后,在主块上执行事务提交的线程将一直等待,直到至少有一个半同步从服务器确认已收到所有事件交易,或直到发生超时。
² 只有事件写入中继日志并刷新到磁盘后,从设备才会确认收到事务的事件。
² 如果在没有任何从服务器确认事务的情况下发生超时,主服务器将恢复异步复制。当至少有一个半同步从站追上时,主站返回到半同步复制。
² 半主动同步复制必须在主,从两端都启用。如果在主服务器上禁用了半同步复制,或者在主服务器上启用了半同步复制,但在无从服务器上启用该功能,则主服务器使用异步复制
当主设备阻塞时(等待从设备提交后从设备的确认),它不会返回到执行事务的会话。块结束后,主站返回到会话,然后可以继续执行其他语句。在这一点上,交易已经在主方承诺,并且其事件的接收已经被至少一个从方确认。
在写入二进制日志的回滚之后,也会发生阻塞,当回滚修改非事务表的事务时,会发生这种情况。即使对事务性表没有任何影响,也会记录回滚事务,因为对非事务性表的修改无法回滚,必须发送给从机。
对于在事务上下文中不存在的语句(也就是说,当没有START TRANSACTION或者 已经开始事务时 SET autocommit = 0),自动提交被启用,并且每个语句隐含地提交。在使用半同步复制的情况下,主块在提交每个这样的语句之后,就像显式的事务提交一样。
异步和完全同步复制进行比较:
² 通过异步复制,主服务器将事件写入二进制日志,从服务器准备就绪时请求它们。不能保证任何事件都会到达任何奴隶。
² 在完全同步复制的情况下,当主服务器提交事务时,所有从服务器也将在主服务器返回执行事务的会话之前提交事务。这样做的缺点是可能会有很多延迟来完成交易。
² 半同步复制属于异步和完全同步复制。主服务器等待,直到至少有一个从服务器接收并记录事件。它不会等待所有的从站确认收到,它只需要收据,而不是从事方已完全执行和提交的事件。
与异步复制相比,半同步复制提供了改进的数据完整性。当提交成功返回时,已知数据至少存在于两个地方(在主机和至少一个从机上)。如果主服务器提交,但主服务器正在等待来自从服务器的确认时发生崩溃,那么事务处理可能没有到达任何从服务器。
半同步复制还通过限制二进制日志事件从主机发送到从机的速度来限制繁忙会话的速率限制。当一个用户太忙时,这会降低速度,这在某些部署情况下非常有用。
半同步复制确实有一些性能影响,因为由于需要等待从站,提交速度较慢。这是增加数据完整性的折衷。减速量至少是向从设备发送提交的TCP / IP往返时间,并等待从设备接收确认。这意味着半同步复制对于通过快速网络进行通信的近距离服务器来说效果最好,对于通过慢速网络进行通信的远距离服务器来说,最差。
部署:
1、加载插件
主:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
从:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
查看是否加载成功:
show plugins;
2.启动
主:
SET GLOBAL rpl_semi_sync_master_enabled = 1;
从:
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
只是临时启动,需要写入配置文件中。
3.重启从库上的IO线程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
4.查看是否在运行
主:
show status like 'Rpl_semi_sync_master_status';
从:
show status like 'Rpl_semi_sync_slave_status';
5. 测试:
查看延迟时间:
show variables like '%rpl_semi_sync%';
从:
stop slave;
主:
create database xudongming;
如果创建库的时间是设置的时间就成功了!!!
1.5 主从同步的故障转移(failover)
MHA设计理念:
主服务器宕掉了,但是多台从服务器的数据和主服务器同步不完整,这时就需要整合多台从服务器中的同步的数据到新的主服务器中,尽量保证数据的完整性。
² 选择新主尽量找一个数据相对新的节点
² 数据补偿:判断新主服务器和其他从节点数据的新旧,补全自己的数据,尽量恢复到比较新的数据,或者去旧主服务器中获取binlog日志补全自己的数据
² 启动新主,将其他从服务器指向新主
² 公布新主
1.6 GTID复制
中继日志(relay log):记录了events和position号
在执行的事务中打上一个唯一标签,这样就可以保证事务之间的连续性及唯一性
为了failover出现的更好的复制,5.6出现,5.7完善
官方定义:
全局事务标识符(GTID)是创建的唯一标识符,并与在源(主)服务器上提交的每个事务相关联。此标识符不但是唯一的,而且在给定复制设置中的所有服务器上都是唯一的。所有交易和所有GTID之间都有一对一的映射关系。是我们为了更好做failover而出现的复制方式
一个GTID被表示为一对坐标,用冒号(:)分隔。
GTID = source_id :transaction_id
7E11FA47-31CA-19E1-9E56-C43AA21293967:29
[root@web01 ~]# cat /application/mysql/data/auto.cnf
[auto]
server-uuid=0b920fba-d0fa-11e7-aae4-000c292741de
注意:如果是克隆的mysql数据库,那么server-uuid相同会导致slave-IO无法启动,需要修改server-uuid
1.6.1 GTID新特性
(1).支持多线程复制:事实上是针对每个database开启相应的独立线程,即每个库有一个单独的(sql thread).
(2).支持启用GTID,在配置主从复制,传统的方式里,你需要找到binlog和POS点,然后change master to指向.
在mysql5.6里,无须再知道binlog和POS点,只需要知道master的IP/端口/账号密码即可,因为同步复制是自动的,MySQL通过内部机制GTID自动找点同步.
(3).基于Row复制只保存改变的列,大大节省Disk Space/Network resources和Memory usage.
(4).支持把Master 和Slave的相关信息记录在Table中
原来是记录在文件里,记录在表里,增强可用性
(5).支持延迟复制
部署过程
环境:
需要两台mysql数据库服务器,一台为主服务器,一台为从服务器。
1.修改配置文件:
主
[mysqld]
log_bin = /tmp/log-bin
binlog-format = row
basedir = /application/mysql/
datadir = /application/mysql/data
socket = /application/mysql/tmp/mysql.sock
server_id = 1
gtid-mode = on #启用gtid类型,否则就是普通的复制架构
enforce-gtid-consistency = true #强制GTID的一致性
log-slave-updates = 1 #slave更新是否记入日志
autocommit = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
character_set_server=utf8
[client]
socket = /application/mysql/tmp/mysql.sock
从
[mysqld]
log_bin = /tmp/log-bin
binlog-format=ROW
basedir = /application/mysql/
datadir = /application/mysql/data/
server_id = 2
socket = /application/mysql/tmp/mysql.sock
gtid-mode = on
enforce-gtid-consistency = true
log_slave_updates = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
character_set_server=utf8
autocommit = 1
[client]
socket = /application/mysql/tmp/mysql.sock
注意:如果是新建的数据库可以不需要从库初始化;如果不是需要从库初始化,同步主从的结构属性
2.在主服务器添加复制用户
grant replication slave on *.* to repl@'10.0.0.%' identified by '123';
3. 在从服务器上设置change master
mysql> change master to
master_host='10.0.0.51',
master_port=3306,
master_user='repl',
master_password='123456',
master_auto_position=1;
4. 开启slave
start slave;
5、查看效果
在主库中添加一个数据,查看master
mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000005 | 544 | | | 9cd29dbb-d003-11e7-a49d-000c29310c49:1-2 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
mysql>
再从库中查看slave:
mysql> show slave statusG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.52
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 544
Relay_Log_File: DB03-relay-bin.000002
Relay_Log_Pos: 754
Relay_Master_Log_File: mysql-bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 544
Relay_Log_Space: 957
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 52
Master_UUID: 9cd29dbb-d003-11e7-a49d-000c29310c49
Master_Info_File: /application/mysql-5.6.36/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 9cd29dbb-d003-11e7-a49d-000c29310c49:1-2
Executed_Gtid_Set: 9cd29dbb-d003-11e7-a49d-000c29310c49:1-2,
e19e3a5b-d33f-11e7-b9b6-000c29af0efd:1-123
Auto_Position: 1
1 row in set (0.00 sec)
mysql>
1.6.2 GTID的生成和生命周期由以下步骤组成:
1.事务在主服务器上执行并提交。
使用主服务器的UUID和此服务器上尚未使用的最小非零事务序列号为该事务分配一个GTID; GTID被写入到master的二进制日志中(紧接在日志中的事务本身之前)。
2.在将二进制日志数据发送到从站并存储在从站的中继日志中,从站读取GTID并设置其gtid_next系统的值变量为这个GTID。这告诉奴隶,下一个事务必须使用这个GTID记录。
3.从站设置gtid_next在会话上下文中。
从机检查以确保此GTID尚未用于在其自己的二进制日志中记录事务。当且仅当这个GTID没有被使用时,从机才会写GTID并应用这个事务(并把事务写到它的二进制日志中)。通过首先读取和检查事务的GTID,在处理事务本身之前,从服务器不仅保证不具有此GTID的以前事务已经被应用于从服务器,而且还确保没有其他会话已经读取了该GTID但还没有提交相关的交易。换一种说法。
4.因为gtid_next不为空,所以从机不会为这个事务生成一个GTID,而是把存储在这个变量中的GTID(即从主机获得的GTID)立即写入二进制日志中。
1.6.3 最简单的GTID复制拓扑的启动过程中的关键步骤(由一个主站和一个从站组成)
- 如果复制已经在运行,则通过将它们设置为只读来同步这两个服务器。
- 停止两台服务器。
- 使用GTID,二进制日志记录和从属更新日志记录启用以及对禁用基于GTID的复制不安全的语句重新启动这两个服务器。另外,服务器应该以只读模式启动,并且应该防止从站启动从站SQL和I / O线程。
- 指示从服务器使用主服务器作为复制数据源并使用自动定位。完成这一步所需的SQL语句在本节后面的例子中描述。
- 采取新的备份。包含没有GTID的交易的二进制日志不能在启用了GTID的服务器上使用,因此在此点之前进行的备份不能用于新配置。
- 启动从服务器,然后在两台服务器上再次禁用只读模式,以便他们可以接受更新。