(注意:以下在数据库中执行的语句大小写无区别)
事务
注意:只有事务型存储引擎支持此类操作
事务的开启与结束,格式如下:
start transaction;
………(执行操作内容)
commit(表示提交并结束)或者 rollback(表示取消之前操作并结束)
默认情况下,事务是自动提交的,为了保证在对数据进行操作后有回环余地,建议设置为不自动提交,可在编辑数据库相关信息时,设置如下变量:
set autocommit = 0
事务也支持保存点,可以在每个操作执行后,对其进行标签标记,这样便于后续后悔操作时,不需要全部取消,可取消至某个保存点:
savepoint 标签
rollback to 标签 表示回到指定标签保存点的操作后
release savepoint 标签 表示取消某个标签
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
事务有不同的隔离级别,分为以下四种,并且逐级提高严格性
在已经有开启数据库使用的情况下,并对某表进行修改操作时,另开端口进入到数据库中查询该表时:
第一种:READ UNCOMMITTED
可读取到修改信息后的数据,包括未提交的,产生脏读。
第二种:READ COMMITTED
会读取提交后的数据,若多次提交,则会读取到不同的数据,产生不可重复读
第三种:REPEATABLE READ(默认使用)
会一直读取修改前的旧数据,产生幻读。
第四种:SERIALIZABILE
已开端口未提交的读事务,会阻碍其他端口的修改操作;未提交的修改事务,会阻碍读事务
(注意:前三种都是无锁状态,第四种是加上了写锁)
修改事务的级别变量为:tx_isolation(进入数据库单次有用)
若需要永久生效,则在/etc/my,cnf中[ mysqld ]块中加入如下:
transaction-isolation=指定级别
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
当出现上述第四种事务隔离级别时,根据实时情况,可利用show processlist查看占用事务的用户信息以及id号,然后利用“kill id号”强制结束其事务进程。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
日志
事务日志:
只适用于事务型存储引擎,记录整个数据库的操作过程
以下几个变量可根据生产情况进行修改:
Innodb_log_file_size 事务的存储大小
Innodb_log_file_in_group 事务日志的成员个数
Innodb_log_group_home_dir 事务日志的文件路径
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
变量 profiling 开启后,
show profiles 可以查看统计执行的什么语句以及消耗的时间
show profile for query“id号”可具体分析每个语句各阶段消耗时间
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
二进制日志:(二进制日志可作为备份数据的重要步骤)
记录提交后的改变数据的SQL语句,以二进制方式存储,并且开启此项功能后,日志一直累积叠加保存操作记录。
为防止突发事件的发生,一般将二进制日志与数据文件分开存放。
二进制记录的格式分为以下三种:
第一种:statement (默认) 语句方式的记录法
第二种:row 根据表内每行都记录(可用于备份使用)
第三种:mixed 根据系统自行判断
可使用变量 binlog_format来进行修改
若是需要启用二进制文件则需要启用两项内容:
sql_log_bin变量设为 on 状态(默认为on)
log_bin选项加入到配置文件中,并建议指定与数据文件不同的路径
(二进制文件的初始大小为245 bites,并且在文件写满后,自动生成下一个)
使用flush logs可生成新的日志文件
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
二进制日志客户端命令工具:mysqlbinlog
此命令的作用在于可将mysql里执行的语句通过重定向导入到文件中,然后在需要时利用客户端命令“mysql < 此文件”重新作用于数据库
mysqlbinlog OPTIONS + 二进制文件 查看相关信息
OPTIONS包含以下:(也可省略)
--start-position=…… 起始位置
--stop-position=…… 结束位置
--start-datetime=…… 起始时间
--stop-datetime=…… 结束时间
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
备份与还原
完全备份
增量备份:相对于最近一次备份发生变化的数据进行备份
差异备份:相对于最近一次的完全备份发生变化的数据进行备份
备份分为冷备(需停服务)、温备(类似加读锁)、热备(读写仍可进行)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LVM逻辑卷快照备份实验(先对数据库加锁,快照结束后立即解锁,近乎热备)
步骤方法如下:
第一步:建立逻辑卷,用来挂载数据库文件,以及二进制文件
echo -e "n\n\n+1G\nt\n6\n8e\nw\n" | fdisk /dev/sda &> /dev/null
pvcreate /dev/sda6
vgcreate vg0 /dev/sda6
lvcreate -n mysqldata -L 100M vg0
lvcreate -n binlogs -L 200M vg0
mkfs.xfs /dev/vg0/mysqldata
mkfs.xfs /dev/vg0/binlogs
mkdir /data/{mysqldata,binlogs} -pv
chown -R mysql.mysql /data/
然后在/etc/fstab配置文件中,写入挂载信息,进行挂载
第二步:将原有数据拷入指定数据目录中,重新指定数据库、二进制日志路径
cp -av /var/lib/mysql/. /data/mysqldata/
vim /etc/my.cnf
[mysqld]
log_bin=/data/binlogs/mysql-bin
datadir=/data/mysqldata/
systemctl start mariadb(启动服务)
第三步:创建快照
mysql -e "flush tables with read lock"(将所有表锁为只读)
mysql -e 'SHOW MASTER STATUS'> /root/bin.log(记录二进制文件位置并导出到文件,以便于后期还原的使用)
lvcreate -n mysqldatasnap -s -L 100M -p r /dev/vg0/mysqldata(创建数据库文件只读型快照)
mysql -e "unlock tables"(解锁)
若是需要达到几乎热备的情况,可以在命令行以“;”隔开,一行输入执行。
第四步:在数据库中进行一些增删改操作。
第五步:对数据库快照文件做备份,然后删除快照
将数据库快照临时挂载,因为数据库逻辑卷和其快照UUID有冲突,所以挂载时需要加入选项:
mount -o nouuid,norecovery /dev/vg0/mysqldatasnap /mnt/
cp -a /mnt/ /backup/ (拷贝至指定文件夹)
umount /mnt/
lvremove /dev/vg0/mysqldatasnap (是为了不影响数据库工作时性能)
上述步骤是完全的实现了数据的拷贝,接下来的步骤就是模拟的破坏实验
第六步:停止服务,删除数据库,此时若是再次启动服务,仍能打开,是因为会自动生成初始化数据库,但是没有了之前操作的数据。
第七步:开始还原数据
cp -a /backup/ /data/mysqldata/(将备份数据重新拷入到原目录中)
此时可以启动服务,但是用户也会直接连接上去,而且此时数据还没恢复,所以修复过程中不应该让用户连接,可以在/etc/my.cnf配置文件中选项:
skip-networking(在启动服务后可跳过网络自己连接)
为了进一步能够还原做好快照后到破坏数据前这中间段用户进行操作发生的日志,可以在mysql中使用 “flush logs”生成一个新的初始化日志来进行隔离分辨。
第八步:根据mysql中“show master logs”查询的二进制日志情况,利用二进制日志还原至数据库最新状态
cd /data/binlogs/
mysqlbinlog --start-position=245 mysql-bin.000001 > /root/sqlbin.log
mysqlbinlog mysql-bin.000002 >> /root/sqlbin.log
……
(表示将从需要的初始二进制文件开始,到破坏数据前最新的二进制文件都导入到指定文件中)
mysql < /root/sqlbin.log (将此文件重新导回到数据库中执行)
第九步:删除加入到配置文件/etc/my.cnf配置文件中选项:skip—networking,重新启动服务,则最终还原成功。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
逻辑备份工具:mysqldump,客户端命令
Options:
-A 备份所有数据库,包括create database
-B “表” 备份指定表,可多个表一起,包括create database
--master-data 会记录做备份时的二进制日志位置,便于后续还原操作
-F 每备份一个数据库,会刷新一次日志
--single-transaction 只适用于InnoDB,保证事务的一致性,只支持数据的增、删、改。
对InooDB生产环境建议使用的策略:
mysqldump –uroot –A –F –E –R --single-transaction --master-data=1 --flush-privileges --triggers --hex-blob > 指定文件
对MyISAM生产环境建议使用的策略:
mysqldump –uroot –A –F –E –R –x --master-data=1 --flush-privileges --triggers --hex-blob > 指定文件
(注意:实际生产中还会有选项“-p密码”)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
实验:对数据库的增量备份还原
因为增量备份的还原需要涉及到二进制日志,所以需要在配置文件/etc/my.cnf中加入选项:log-bin ,然后开启数据库服务。
具体实验步骤如下:
第一步:对已有数据库先做一次完全备份
mysqldump -A -F --single-transaction --master-data=2 > /app/mysqldata
第二步:假设进入到hellodb数据库中,对students表进行实验修改,如下:
insert into students (name,age) values ('ruixiaoyu',18)
insert into students (name,age) values ('hongxixiang',20)
在以上操作后,又误删除了学生表:
drop table students
第三步:在删除students表后,又对其他的表进行了操作,如下:
select * from teachers;
insert teachers values (5,'yaochen',50,'M')
第四步:假设突然发现了这个重大失误,则此时需要立即在该数据库中执行读锁设置:
flush tables with read lock
这是为了以防我们在进行还原操作中,还会有其他用户一直进行数据的修改。
第五步:需要根据以完全备份的/app/mysqldata,来查看到记录的二进制日志的记录位置,然后利用如下命令,对备份之后的新增二进制日志内容进行备份:
mysqlbinlog --start-position=245 mariadb-bin.000002 > /app/binlogs
第六步:在/app/binlogs文件中,查找出误操作的步骤,并将之移除,并且删除原有数据库信息:
rm -rf /var/lib/mysql/*
第七步:为了在恢复过程中,不让用户在对数据库有操作影响,则在配置文件/etc/my.cnf中,加入选项: skip-networking,然后启动服务
第八步:导入完全备份文件以及增量备份文件,进行还原:
mysql < mysqldata
mysql < binlogs
第九步:删除/etc/my.cnf中选项: skip-networking,并重启服务。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Xtrabackuo 工具
唯一开源且能够对InnoDB数据库进行热备,而且可以自动实现备份检验。
此工具最基本的工作原理就是拷贝,通过将备份处理后的数据存入指定文件中,
然后再将该指定文件中内容复制进已删除干净的原数据库存放目录中,修改权限后,实现还原。
主要涉及的几个选项如下:
1.—backup 表示要进行备份
2.—target-dir 表示备份数据存放的目录
3.--incremental 表示创建一个增量备份,但是需要指定基于前一次完全备份或者增量备份的目录
4.--incremental-basedir 表示的就是—incremental所指的目录
5.--incremental-dir 表示还原时增量备份的目录
6. —prepare 表示还原时进行预处理备份数据
7. --apply-log-only
一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处理不一致状态。此选项作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态 。此选项只需在最后一次增量备份还原使用。
8. —redo-only 在最后一次增量备份前的增量备份还原时使用,确保事务的不回滚
9. —copy-back或者—move-back 将备份数据拷贝或移动至源数据库目录中
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
实验:使用xtrabackup工具进行增量备份与还原
假设实验有两次增量,为了便于观察,可单独建立不同文件夹来进行区分
mkdir /app/{full,inc1,inc2}
具体步骤如下:
在原主机上,进行热备操作:
第一步:先对数据库进行完全备份
xtrabackup --backup --target-dir=/app/full
第二步:假设在数据库进行第一次修改
insert into students (name,age) values ('zhangqiling',0)
并进行第一次增量备份
xtrabackup --backup --target-dir=/app/inc1 --incremental-basedir=/app/full
第三步:假设在数据库进行第二次修改
insert teachers values (7,'wanjianyi',60,'M')
并进行第二次增量备份
xtrabackup --backup --target-dir=/app/inc2 --incremental-basedir=/app/inc1
第四步:将此三个备份数据拷入到新主机中
scp -r /app/* 172.18.122.241:/app/
第五步:确保新主机服务暂停,在新主机上进行备份数据的预处理
xtrabackup --prepare --apply-log-only --target-dir=/app/full
xtrabackup --prepare --apply-log-only --target-dir=/app/full --incremental-dir=/app/inc1
xtrabackup --prepare --target-dir=/app/full --incremental-dir=/app/inc2
第六步:删除新主机下原目录下数据,并将处理后数据拷贝过去
rm -rf /var/lib/mysql/*
xtrabackup --copy-back --target-dir=/app/full
第七步:需要修改拷贝后的数据文件属性
chown -R mysql.mysql /var/lib/mysql/
第八步:启动服务,即可使用。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
复制
通过proxy来实现MySQL的读写分离,达到主从复制的应用。
主从复制是依赖于二进制日志的,所以要实现则必须启用二进制日志功能。
工作原理:主服务器数据的更新===>二进制日志===>主服务器的dump线程===>传达给从服务器的io线程===>存放在中继日志===>SQL线程读取中继日志中的内容===>实现从服务器的数据更新
(主从数据的更新不可避免的会存在延迟,这是因为主服务会根据多个io线程来开启对应的dump线程,所以正常也会采取异步复制)
一般情况下:主服务器写,从服务器读(配置文件中加入read_only=on)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
主服务器刚开始运行下的情况,主从复制的搭建:
1.二进制日志,主服务器必须启用,从服务器建议启用(以防主服务器发生故障时,从服务器临时充当主服务器)
2.配置文件/etc/my.cnf中主从服务器的服务号server_id必须保证唯一性
3.在主服务器上指定拥有复制权限“replication slave”的用户:
GRANT REPLICATION SLAVE ON *.* TO '用户'@'IP' IDENTIFIED BY '密码'
4.在从服务器上使用3步骤创建的用户连接主服务器:
CHANGE MASTER TO MASTER_HOST='IP',
MASTER_USER='用户',
MASTER_PASSWORD='密码',
MASTER_LOG_FILE='mariadb-bin.xxxxx',
MASTER_LOG_POS=#;
5.从服务器启动复制线程:start slave
(注意:搭建成功后,并已经start slave,若从服务器重新启动服务,此时会自动启动io、SQL两个线程,继续实现主从复制功能)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
当主服务器已经运行一段时间后,需要新加从服务器,实现方法:
1.利用mysqldump命令,对主服务器进行备份,此时 --master-data 选项可指定为1,这样可保证CHANGE MASTER TO……语句没被注释,然后将备份文件拷贝至从服务器中;
2.主服务器其他配置和(主服务器刚开始运行下的情况,主从复制的搭建)的实验一样;
3.从服务器添加server_id号,并将(主服务器刚开始运行下的情况,主从复制的搭建)实验的4步骤内容加入到备份文件中;
4.从服务器导入备份文件,启动服务,启动start slave,完成搭建。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
当一主多从情况下,主服务器突然宕机,此时需要临时启用某个从服务器为主,可以手动在从服务器上stop slave并且利用reset slave all清除原主从关系属性,然后重新以自己为主建立主从关系临时使用。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
为缓解主服务器的工作压力,可以建立级联复制,也就是M对S,S对SS。
1.需要开启S的二进制日志功能
2.因为数据复制传输的原理是通过二进制日志,但是S自身只会主动将M传递过来的数据记录到中继日志中,这样SS就不能够通过 S来进行数据的更新,所有需要在S的配置文件中加入“log_slave_updates”选项,来实现中继日志的内容更新到二进制日志中
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
半同步复制
在M对多S的情况下,保证先令一个S同步成功后,然后在回应用户的请求,这样可保证数据的安全,以及用户的体验速度。
建立的方法:分别在M和S上安装插件,并启用相关的变量
M上执行:
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql> SET GLOBAL VARIABLES rpl_semi_sync_master_enabled=1;
S上执行:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> SET GLOBAL VARIABLES rpl_semi_sync_slave_enabled=1;
若是S是在已有主从的情况下增加插件,需要重新启动io和SQL线程
若是需要卸载此插件的话,只需执行:
Uninstall rpl_semi_sync_master|slave
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在主从复制过程中,还可以对不同的数据库设定不同的复制权限
第一种:基于主服务器二进制日志的限定,在/etc/my.cnf中加入如下选项:
binlog_do_db= 数据库白名单列表
binlog_ignore_db= 数据库黑名单列表
但是二进制日志是主从复制的必要条件,所以这种方法不建议使用
第二种:基于从服务器的SQL THREAD从中继日志读取信息,在/etc/my.cnf中加入如下选项:
replicate_do_db|table= 指定复制库的白名单
replicate_ignore_db|table= 指定复制库的黑名单
若是白名单指定的数据库或表,则二进制日志就会只记录该数据库操作信息;
若是黑名单指定的数据库或表,则二进制日志就不会记录该数据库操作信息;
若是同一数据库在两者里都有,则只有白名单生效。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
复制加密(基于SSL/TLS加密)
实现的步骤:
1.在另外的独立的服务器上生成私钥来创建自签名CA证书,
openssl genrsa > cakey.pem
openssl req –new –x509 -key cakey.pem -out cacert.crt -days 3650
另外生成给主服务使用的私钥和证书申请文件:
openssl req -newkey rsa:2048 -nodes -keyout master.key > master.csr
给从服务器生成私钥和证书申请文件:
openssl req -newkey rsa:2048 -nodes -keyout slave.key > slave.csr
2.给主服务器和从服务器颁发证书文件
openssl x509 -req -in master.csr -CA cacert.crt -CAkey cakey.pem -set_serial 01 -days 100 > master.crt
openssl x509 -req -in slave.csr -CA cacert.crt -CAkey cakey.pem -set_serial 02 -days 100 > slave.crt
3.然后将主从服务器需要的文件分别拷贝给它们,存放在指定的文件夹中,假设存放在/app/ssl/下
4.注意要保证拷贝后的文件的读权限
5.在主服务器的/etc/my.cnf中加入如下选项:
ssl(可省略)
ssl-ca=/app/ssl/cacert.crt
ssl-cert=/app/ssl/master.crt
ssl-key=/app/ssl/master.key
然后启动服务,创建复制使用账户,并强制其加密
grant replication slave on *.* to 'rui'@'172.18.122.%' identified by 'centos' require ssl
6.从服务器在配置文件中加入如下选项:
ssl(可省略)
ssl-ca=/app/ssl/cacert.crt
ssl-cert=/app/ssl/slave.crt
ssl-key=/app/ssl/slave.key
然后启动服务,并使用change master to语句执行相关信息,注意需要加上master_ssl=1
7.从服务器启动线程 start slave,则开始实现同步
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MHA高可用(Master High Availability)
原理:建立一个manager管理者,它通过ssh协议与各集群(application)的主从节点进行通讯,在主服务器出现故障时,可自动的将主节点转移至其它从节点,提升某一从节点为新的主节点使用,将其余的从节点指向新的主节点。(MHA可自动发现从节点更新数据的新旧,优先提用数据较新的从节点,并会将其read_only变量设为不启用)
MHA需要由两部分组成,mha4mysql-manager和mha4mysql-node工具包
实现MHA的步骤:(注意:各节点间的时间务必保持一直)
1.首先需要在作为管理器的服务器上安装MHA需要的两工具包(先node后manager),各集群节点上只安装mha4mysql-node工具包;
2.在作为管理的服务器的配置文件(需要手工建立,每个集群可单独设立)中为所有的集群进行global设置,以及为每个单独的集群设立特殊设置;
[server default] (全局)
user=管理用户民 (用来连接被管理的集群)
password=密码
manager_workdir=管理的工作目录
manager_log=管理日志文件
remote_workdir=远程的工作目录
ssh_user=SSH用户
repl_user= 主从复制的用户
repl_password=密码
ping_interval=1
(以下是针对单独的集群设置)
[server1]
hostname=IP
candidate_master=1
[server2]
hostname=IP
candidate_master=1
[server3]
hostname=IP
candidate_master=1
(注意:这里的candidate_master=1选项,表示主服务器宕机后,管理节点会根据有此选项的从服务器中来挑选当新主)
3.建立主从复制的集群,主从服务器都应在配置文件中加入选项skip_name_resolve,以防远程连接出现错误;
主服务器中mysql中另外建立管理节点的账号信息:
grant all on *.* to 用户名@‘IP’ identified by ‘密码’;
从服务器需要加入如下选项:
read_only (只读)(在主服务器宕机后,从服务中被挑选为充当新主服务器后会自动关闭此选项)
relay_log_purge=0 (不清除中继日志)
4.管理器和集群节点之间互相建立ssh key验证,
5.为保证MHA的正常运行,可在上述步骤设置好后,进行验证
masterha_check_ssh --conf=配置文件
masterha_check_repl --conf=配置文件
并启动监控(默认前台执行,建议手动设置为后台)
masterha_manager --conf=配置文件
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
延伸:
因为调度器(proxy)是分离主从读写的,在MHA启用情况下,调度器还需要能够有重新指定ip的操作,keepalive则可以很好地完成此项功能
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Galrea Cluster高可用
目前有两种版本可以实现:
Percona Xtradb Cluster及MariaDB Cluster
原理:多节点同时可进行读和写,同步无延迟并且并发复制,基于WSREP协议,不依赖于二进制日志,是直接拷贝数据文件块来进行复制。
(WSREP:MySQL extended with the Write Set Replication)
(至少需要三个节点来实现,并且不能安装另外的mysql服务包)
实现步骤:(这里针对MariaDB Cluster )
1.在每个集群节点上都安装指定的MariaDB-Galera-server包
2.在配置文件/etc/my.cnf.d/server.cnf中定义如下选项:
wsrep_provider = /usr/lib64/galera/libgalera_smm.so 定义模块
wsrep_cluster_address=“gcomm://IP1,IP2,……”定义集群的成员ip
binlog_format=row 二进制日志记录方式为行
default_storage_engine=InnoDB 默认引擎为InooDB
innodb_autoinc_lock_mode=2 锁模式
bind-address=0.0.0.0 将端口绑定在所有IP
3.首次启动服务时,第一个节点启东时需要使用以下选项:
/etc/init.d/mysql start --wsrep-new-cluster
表示创建集群
其余节点正常启动即可:service mysql start
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
实际生产中建议的my.cnf配置文件中的选项:
下面的“#”表示设定的数值
Innodb_file_per_table=1 数据库数据单独存放
max_connections=# 允许的最大会话连接数
back_log=# 最大会话连接数达到时可另外保持的连接数
max_connect_errors=# 连接次数超过指定,会组织此主机连接
open_file_limit=# 所有线程打开表的数量
innodb_buffer_pool_size=# 设置缓冲池,可相对的提高数据库性能
innodb_log_file_size=# 事务日志文件的大小
innodb_log_files_in_group=# 事务日志文件的总数