【RDB】MariaDB 之事务、复制、集群
目录
- 简介
- 安装启动
- 权限
- 事务
- 脏读、不可重复读、幻读
- MVCC
- 复制
- 异步复制
- 半同步复制
- GTID复制
- 集群(Galera)
- 配置
- 监控(Zabbix)
简介
环境:
- CentOS 7.4.1708
- MariaDB 10.3.9
简介:
- MySQL 由 MySQLAB 公司开发。
- MariaDB 是 MySQL的一个分支,它是 MySQL 之父 Monty Widenius 开发
- 目前很多知名的 Linux 发行版已经使用 MariaDB 替代了 MySQL。如:RHEL 7,CentOS 7。
MariaDB的优点:
- 插件式存储引擎
- 单进程多线程
- MySQL 有走向封闭的趋势
- MariaDB 高度兼容 MySQL
安装启动
安装
查看是否安装MariaDB rpm包:
rpm -qa | grep MariaDB
在 CentOS 7.4 默认源中的 MariaDB 仍为5.x版本,当需要 10.x 版本时,可通过添加第三方源实现:
echo -e "[MariaDB]\nname = MariaDB\nbaseurl = http://yum.MariaDB.org/10.3/centos7-amd64\ngpgkey=https://yum.MariaDB.org/RPM-GPG-KEY-MariaDB\ngpgcheck=1" > /etc/yum.repos.d/MariaDB-10.3.repo
官方源比较慢的情况,可以使用清华镜像源(根据需要执行yum clean all):
echo -e "[MariaDB]\nname = MariaDB\nbaseurl = https://mirrors.tuna.tsinghua.edu.cn/mariadb//mariadb-10.3.9/yum/centos/7.4/x86_64/\ngpgkey=https://yum.MariaDB.org/RPM-GPG-KEY-MariaDB\ngpgcheck=1" > /etc/yum.repos.d/MariaDB-10.3.repo
安装MariaDB客户端(包含MariaDB-common、MariaDB-client下载9MB 安装50M):
yum install -y MariaDB.x86_64
安装MariaDB服务端(包含MariaDB-common、MariaDB-client、MariaDB-server):
yum install -y MariaDB-server.x86_64
查看 MariaDB 安装的文件:
rpm -ql MariaDB-server
或 rpm -ql MariaDB-client
目录文件 | 说明 |
---|---|
/etc/my.cnf |
默认配置文件 |
/var/lib/mysql/ |
文件夹下是 MariaDB 数据库目录、错误日志和 socket 文件 |
mysql |
mysql cli 客户端 |
mysqldump |
备份工具,基于 mysql协议 向 mysqld 发起查询,将结果转化为insert语句导出。 |
mysqladmin |
基于 mysql协议 管理 mysqld。 |
mysqlimport |
mysql 导入工具 |
注意:
- MariaDB 在 10.X 版本以前包名为 mariadb,之后为 MariaDB。但服务名仍为 mariadb:service mariadb start;
启动
启动MariaDB服务:
service mariadb start
初始化(为root设置密码,删除测试数据库、匿名用户):
/usr/bin/mysql_secure_installation
登录mysql查看版本:
mysqladmin version -p123123
一键卸载MariaDB且清除MariaDB数据(便于调试):
yum -y remove `rpm -qa | grep MariaDB` && rm -rf /var/lib/mysql
权限
- 授权表:db、host、user、table_priv、column_priv、procs_priv
- 用户账号:'username'@'host' host:主机名、IP、通配符(%,_)
- 创建用户:create user 'username'@'host' [identity by 'passwd']
- 查看用户权限:show grants for 'username'@'host';
- 重命名用户:RENAME USER oldname TO newname;
- 删除用户:DROP USER 'username'@'host';
- 修改密码:SET PASSWORD
允许root远程访问:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123123' WITH GRANT OPTION;
- WITH GRANT OPTION 表示该用户可以将自己的权限授权给别人
- 如果只授予部分权限,其中 all privileges 改为 select,insert,update,delete,create,drop,index,alter,grant,references,reload,shutdown,process,file 其中一部分。
精确到列的权限:
GRANT SELECT(Id,Name) ON testdb.Users TO testuser@'%' IDENTIFIED BY '123123'
重载授权表:
FLUSH PRIVILEGES;
忘记root密码:
- systemctl stop mariadb.service
- mysqld_safe --skip-grant-tables
- mysql -u root
- update mysql.user set password=PASSWORD('newpassword') where User='root’;
- flush privileges;
- systemctl restart mariadb.service
事务
MySQL按照标准SQL定义了4种隔离级别,较低的隔离级别,能带来更高的并发和更低的系统开销。
- 未提交读(READ-UNCOMMITTED)
- 可以读到未提交的修改记录
- 读已提交(READ-COMMITTED)
- 只要提交的修改记录(包括其他的事务)都可以读到
- 基于MVCC并发控制
- 可重复读(REPEATABLE-READ)
- 在事务开始第一次读取后,其他事务可修改读到的数据,但读到的数据不会被修改(幻读情况下会新增和减少)
- 基于MVCC并发控制
- 串行读(SERIALIZABLE)
- 事务开始后发生对数据的操作(即使发生读操作),其他事务都不能修改数据
- 基于锁控制:实际上串行读在RR级别上隐式加gap间隙共享锁:
select ... for update
备注:
set tx_isolation='READ-UNCOMMITTED';
调整当前 session 隔离级别select @@tx_isolation
查看当前 session 隔离级别show processlist;
查看 mysql 连接状态
在4种隔离级别中又分别存在不同的读问题:
- 脏读(dirty reads)
- 在 READ-UNCOMMITTED 级别会出现读到未提交的数据
T1:select * from users where id = 1;
T2:insert into `users`(`id`, `name`) values (1, 'foo'); -- 事务未提交
T1:select * from users where id = 1; -- 会读到
- 不可重复读(non-repeatable reads)
- 在 READ-COMMITTED 级别会出现先后读取不一致的情况(关注点:读-读)
T1:select * from users where id = 2;
T2:insert into `users`(`id`, `name`) values (2, 'foo');
T2:commit;
T1:select * from users where id = 2; -- 会读到
- 幻读(phantom reads)
- 在 REPEATABLE-READ 级别会出现插入事先不存在的记录时,发现(insert会隐式的select)这些数据又存在(关注点:读-写)
T1:select * from users where id = 3; -- 判断是否有 Id = 3 的数据,没有则插入
T2:insert into `users`(`id`, `name`) values (3, 'bar'); -- 执行成功
T1:insert into `users`(`id`, `name`) values (3, 'bar'); -- 执行失败,由于 T1 发生幻读,不能支持该业务执行
- 锁读(lock reads)
- 在 SERIALIZABLE 级别会出现读的数据无法修改情况
T1:select * from users where id = 3;
T2:update `users` set `name` = 'baz' where `id` = 3; -- 执行失败,由于 Id = 3 的数据被锁
注意:
- 在同1次连接上,上次事务未提交,执行
start transaction;
。会自动提交该连接上次的修改。
MVCC机制:
在 MVCC 之前,RC 和 RR 隔离级别是怎么工作?
在 MVCC 之前,是单纯依赖锁的机制实现隔离级别。
当T1修改1条数据时加上排他锁,T2事务的读操作会被阻塞。当T1提交或回滚,锁被释放时,才能读取到提交的数据。但一般应用都是读多写少,导致系统处于大量的等待中,非常低效。
有了 MVCC 机制后,效果是怎么样?
有了 MVCC 后,当数据被修改时,会生成1个副本出来供其他事务读取。不会出现阻塞情况,读的性能会大幅提升。只有 SERIALIZABLE 级别的读操作才有可能被阻塞。(MVCC应用在RC和RR隔离级别上)
MVCC 具体如何实现的?
- 在 MySQL 中 MVCC 是在 InnoDB 存储引擎上实现的。
- InnoDB 为每行数据增加3个字段:隐藏的ID、当前事务ID、回滚指针。
- MVCC 依赖 undo log 和 readview 来确定数据的可见性。
undo log:记录了原始数据的多个副本,用来回滚和提供其他事务读取
readview:记录了活动事务Id,用来确定可见哪个副本
- 在每个事务开启执行第1条语句的时候,会创建1个readview。
- 将行数据的当前事务TRID 与 readview中的事务RVID 比较
- TRID < 所有的 RVID:可见(之前的事务创建)
- TRID > 所有的 RVID:不可见(新事务创建)
- TRID 在 RVID 中存在:不可见(活动的事务创建)
- TRID 在 RVID 中不存在:可见(内存中commit或自己创建)
- 当数据不可见时,会从数据的回滚指针获取数据重新判断一遍
- RC 和 RR的区别:
- RR 在事务开始只创建1次 readview
- RC 在事务每次执行语句都会创建 readview
事务提交过程及日志变化:
- 用 排他锁 锁定该行
- 记录 redo buffer
- copy 数据到 undo buffer
- 内存中修改数据 填写隐藏字段 事务Id 和 回滚指针
commit:
- redo log 文件持久化(innodb_flush_log_at_trx_commit)
- bin log 文件持久化(sync_binlog)(这一步完成能确保故障恢复)
- innodb引擎 commit(数据持久化,undo log)
注意:
- redo log 文件并不一定在commit时才做持久化
- Master Thread 每秒执行一次
- 每个事务提交时
- 当重做日志缓存可用空间 少于一半时
- redo log 是连续的一段存储空间,而修改的数据很可能是随机的区域
- undo log 并非在事务提交完立即释放
- 提交后放入待清理区域,由purge线程判断是否仍有其他事务在使用,来决定是否删除。
- 默认undo log 存储在 idb 表空间中,在 MariaDB 10.0(MySQL 5.7)后通过innodb_undo_directory 、innodb_undo_logs 、innodb_undo_tablespaces 可配置独立文件
主从复制
主从复制能提供水平扩展 数据备份 数据分析 高可用性等,故开启主从复制越来越必要。
复制
MariaDB 主从复制工作3步:
- 主库的数据更改记录到 binlog 中
- 从库将主库的日志 复制到 relaylog 中
- 从库使用 IO 线程请求主库
- 主库使用 dump 线程读取 binlog 传给
- 备库 SQL 线程读取 relaylog 事件,重放到数据库。
配置复制:
- 在主库和从库创建复制账号
- GRANT REPLICATION SLAVE, REPLICATION CLIENT ON . TO repl@'10.0.0.%' IDENTIFIED BY 'p4ssword';
- 配置主库和从库
配置主服务器:
[mysqld]
log_bin = mysql-bin
server_id = 1 # 唯一,可以用IP地址的末几位
从服务器:
[mysqld]
log_bin = mysql-bin
server_id = 2
log_slave_updates = 1 # 重放同时写到binlog
relay_log = /var/lib/mysql/mysql-relay-bin
- 从库启动复制
- MariaDB > CHANGE MASTER TO MASTER_HOST='server1',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='p4ssword',
-> MASTER_LOG_FILE='mysql-bin.000001',
-> MASTER_LOG_POS=0; - MariaDB > START SLAVE;
- MariaDB > SHOW SLAVE STATUS\G
- MariaDB > CHANGE MASTER TO MASTER_HOST='server1',
注意:
- 要填写的复制的POSITION,可以通过
SHOW MASTER STATUS\G
查看 - 启用复制功能不会给服务器太多的开销。(主要是开启 binlog 和 sync_binlog=1 fsync的开销)
- 如果复制配置有问题,可以重置配置信息:
stop slave; reset slave;
半同步复制:
默认复制是单向异步的,也支持半同步复制功能(MariaDB 10.3 后内置不需要单独安装插件)。
- 主库:
set global rpl_semi_sync_master_enabled = 1;
set global rpl_semi_sync_master_wait_point = AFTER_SYNC;
- 从库:
set global rpl_semi_sync_slave_enabled = 1;
semi配置:
配置项|推荐配置值|说明
rpl_semi_sync_master_enabled|ON|开启主库半同步复制
rpl_semi_sync_master_timeout|10000|最多等待从库响应10s
rpl_semi_sync_master_wait_no_slave|ON|当没有从节点时(从节点突然断开)是否继续等待
rpl_semi_sync_master_wait_point|AFTER_SYNC|控制Wait Slave ACK的时机
rpl_semi_sync_slave_enabled|ON|开启从库半同步复制
原理:
- 半同步复制是在事务提交时,等待至少1个从库接收并写到relay log才返回给客户端(Wait Slave ACK)。
- 半同步复制提高数据安全性,但也造成一定的延迟(最少是1次tcp/ip返还的时间)。
- 半同步复制默认AFTER_COMMIT是在bin log持久化及存储引擎提交后再等待从库接收写到relay log,通过rpl_semi_sync_master_wait_point配置为AFTER_SYNC,可以将从库复制操作改到主库存储引擎提交之前。
相当于有异步复制、半同步复制还有个全同步复制,代表为 mysql-cluster性能太差,需要等待所有slave都同步才commit成功(性能太差)
注意:
- 半同步复制数据一致性并不能100%保证,在非常极端情况下,AFTER_SYNC会出现从库数据多的情况,AFTER_COMMIT会出现从库数据丢失的情况。
- AFTER_SYNC 可以让存储引擎commit支持group commit。所以性能安全性都比AFTER_COMMIT好
GTID
从MariaDB 10.0.2开始,GTID会自动启用,在 binlog 中的每个事件组(事务)都会先记录1个GTID。
全局事务ID(简称GTID)由三个用短划线“ - ”分隔的数字组成。例如:0-1-10
- 第一个数字0是域ID,它特定于全局事务ID(以下更多内容)。它是一个32位无符号整数。
- 第二个数字是服务器ID,与旧式复制中使用的相同。它是一个32位无符号整数。
- 第三个数字是序列号。这是一个64位无符号整数,对于登录到binlog中的每个新事件组,它会单调递增。
为什么要使用GTID:
- 以前复制需要确定 binlog 文件名+偏移量。使用GTID则会自动确定。
- 以前通过 relaylog 文件记录复制进度,且和数据同步是独立进行。使用GTID,将会在数据更新的事务中一起更新状态(存在mysql.gtid_slave_pos)
- 更适合MHA时failover。
如何配置:
CHANGE MASTER TO master_use_gtid = { slave_pos | current_pos | no }
- current_pos:当前服务器最后1条binlog命令的gtid记录
- slave_pos:当前(从)服务器最后1次执行重放数据的gtid记录
完整:CHANGE MASTER TO master_host = "127.0.0.1", master_user = "root", master_use_gtid = current_pos;
select @@gtid_slave_pos 可查看slave最后1个gtid。
select @@gtid_current_pos 可查看当前服务器执行的最后1个gtid。
注意:
- MariaDB和MySQL具有不同的GTID实现,并且它们彼此不兼容。
- 完成复制的必要条件主库开启 binlog 日志,相当于开启主库的GTID。从库及时不开启 binlog, slave_pos 也会更新,但自执行的SQL不会影响current_pos。
- SET GLOBAL gtid_slave_pos = ""; 会重置GTID进度。
Galera集群
在MariaDB 5.5和MariaDB 10.0中,MariaDB Galera Server是一个独立的软件包,而不是标准的MariaDB Server软件包。从MariaDB 10.1开始,MariaDB Server和MariaDB Galera Server软件包已经合并,并且在安装MariaDB时会自动安装Galera软件包及其依赖项。Galera部件在配置之前保持休眠状态,如插件或存储引擎。
相比于复制、半同步复制,Galera集群相当于是同步复制。其实现原理完全与 binlog 没有任何关系。
配置步骤:
- 配置
[galera]
# Mandatory settings
wsrep_on=ON
# rpm -ql galera.x86_64 -> /usr/lib64/galera/libgalera_smm.so
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
# DNS名称也有效,IP是性能的首选
wsrep_cluster_address="gcomm://172.17.145.110, 172.18.0.2"
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
- 引导新集群
$ galera_new_cluster(Systemd推荐) - 在多台服务器上开启mysql服务
$ service mariadb start
注意:
- Galera Cluster方式会出现自增ID不连续的情况,可使用GUID由程序生成
配置
命令 | 说明 |
---|---|
mysqld --verbose --help | less |
查看默认配置及配置说明 |
cat /etc/my.cnf | grep -v '^#' | grep -v '^$' |
查看去除注释后的配置文件 |
show [global] variables; |
查看配置 |
set [global] name=value; |
修改配置 |
配置项 | 默认值 | 推荐值 | 说明 |
---|---|---|---|
autocommit | on | off | 是否开启自动提交,默认开启,所有修改操作都会自动开启1个事务,并提交。(影响性能) |
skip-name-resolve | false | true | 跳过IP反解为域名过程,默认关闭,所有连接都会反解IP为域名。(影响性能以及授权) |
innodb_flush_log_at_trx_commit | 1 | 1 | 在事务提交时确保redolog持久化 |
innodb-file-per-table | true | true | 独立表空间,每1个表都以独立文件存储 |
sync_binlog | 0 | 1 | 在事务提交时确保binlog持久化 |
(配置项会不断更新比较重要的)
监控
监控可使用 Zabbix 对MariaDB 做监控。
(实现原理是通过查询 MariaDB 的状态变量实现)
本文地址:https://www.cnblogs.com/neverc/p/9870088.html
【RDB】MariaDB 之事务、复制、集群的更多相关文章
- Mariadb之半同步复制集群配置
首先我们来了解下在mariadb/mysql数据库主从复制集群中什么是同步,什么是异步,什么是半同步:所谓同步就是指主节点发生写操作事件,它不会立刻返回,而是等到从节点接收到主节点发送过来的写操作事件 ...
- Redis高可用复制集群实现
redis简单介绍 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库.Redis 与其他 key - value 缓存产品有以下三个特点: 支持数据的持久化,可以将 ...
- MHA实现mysql高可用复制集群
MHA简述 MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件.在My ...
- Java应用服务器之tomcat会话复制集群配置
会话是识别用户,跟踪用户访问行为的一个手段,通过cookie(存在客户端)或session(存在服务端)来判断本次请求是那个客户端发送过来:常用的会话保持有绑定会话,就是前边我们聊的在代理上通过算法或 ...
- 使用 Bitnami PostgreSQL Docker 镜像快速设置流复制集群
bitnami-docker-postgresql 仓库 源码:bitnami-docker-postgresql https://github.com/bitnami/bitnami-docker- ...
- lcn 分布式事务协调者集群原理
lcn集群原理图: 1.实现原理: 1.1 LCN获取tm协调者注册地址 1. LCN客户端项目启动的时候,首先会注册到事务协调者中去,然后读取配置文件tm事务协调者的注册地址. 2. 向该事务协调者 ...
- 【MySQL】MySQL-主从复制-集群方案-数据一致性问题解决方案 && MySQL备份的各种姿势
1.写性能如何保证:分库分表 2.读性能如何保证:主从结构,实时备份 3.一致性问题怎么解决: 3.1.微博案例:Redis缓存,热数据查询走Redis,主从的延迟通过Redis消除 3.2.支付宝的 ...
- MongoDB搭建ReplSet复制集群
MongoDB的复制集是一个主从复制模式 又具有故障转移的集群,任何成员都有可能是master,当master挂掉用会很快的重新选举一个节点来充当master. 复制集中的组成主要成员 Primary ...
- mysql组复制集群简介
mysql组复制集群拓扑: 环境: centos6.5 mysql5.7.19 一.组复制搭建: 配置hosts文件 再三台服务器上分别启动一个mysql实例,共三个. 参考配置文件如下: serve ...
- 在 TKE 中使用 Velero 迁移复制集群资源
概述 Velero(以前称为Heptio Ark)是一个开源工具,可以安全地备份和还原,执行灾难恢复以及迁移 Kubernetes 群集资源和持久卷,可以在 TKE 集群或自建 Kubernetes ...
随机推荐
- 光杆mdf文件的导入
场景,准备学习SSAS的时候,按照教程在微软下载了示例数据库AdventureWorksDW2012,下载来才发现只有一个mdf文件. 正好今天群里有位兄弟也碰到差不多的问题,客户数据库里的ldf文件 ...
- gh-ost和pt-osc性能对比
haughty_xiao 基于MySQL row格式的复制现在趋于主流,因此可以使用此格式的binlog来跟踪改变而不是触发器.与percona toolkit的pt-online-schem ...
- Collection中的List,Set的toString()方法
代码: Collection c = new ArrayList(); c.add("hello"); c.add("world"); ...
- JDK5新特性之 可变参数的方法
可变参数的方法:不知道这个方法该定义多少个参数 注意: > 参数实际上是数组 > 必须写在参数列表最后一个 package cn.itcast.day24.varparam; import ...
- sql行列转换PIVOT与unPIVOT
基本语法 select * from Mould pivot ( count(ID)for ProductTypeCode in ( [FC], [RCU], [RCD] )) as PVT; wit ...
- [pip] pip命令的安装、卸载、查找方法汇总
比如以selenium的为例 1.打开命令窗口(如果是win10,最好是通过管理员方式打开命令窗口,否则会出现安装时提示访问不拒绝) 2.安装selenium的指定版本,命令:pip install ...
- vue2.0学习笔记之路由(二)路由嵌套+动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- node学习笔记_01 环境搭建
一.下载安装nvm (node版本管理器),方便以后版本切换 nvm list -> 查看node版本(版本最好在8.0以上,不然在vsCode断点调试进不去,跟node版 ...
- Spring IOC 之 SmartInitializingSingleton
使用 实现该接口后,当所有单例 bean 都初始化完成以后, 容器会回调该接口的方法 afterSingletonsInstantiated. 主要应用场合就是在所有单例 bean 创建完成之后,可以 ...
- Python中让MySQL查询结果返回字典类型的方法
import pymysql host='localhost' user='root' passwd='root' port=3306 db='test' db=pymysql.connect( ho ...