目录

  • 简介
  • 安装启动
  • 权限
  • 事务
    • 脏读、不可重复读、幻读
    • 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 版本时,可通过添加第三方源实现:

MariaDB 官方源

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-serverrpm -ql MariaDB-client

目录文件 说明
/etc/my.cnf 默认配置文件
/var/lib/mysql/ 文件夹下是 MariaDB 数据库目录、错误日志和 socket 文件
mysql mysql cli 客户端
mysqldump 备份工具,基于 mysql协议 向 mysqld 发起查询,将结果转化为insert语句导出。
mysqladmin 基于 mysql协议 管理 mysqld。
mysqlimport mysql 导入工具

注意:

  1. 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

权限

  1. 授权表:db、host、user、table_priv、column_priv、procs_priv
  2. 用户账号:'username'@'host' host:主机名、IP、通配符(%,_)
  3. 创建用户:create user 'username'@'host' [identity by 'passwd']
  4. 查看用户权限:show grants for 'username'@'host';
  5. 重命名用户:RENAME USER oldname TO newname;
  6. 删除用户:DROP USER 'username'@'host';
  7. 修改密码:SET PASSWORD

允许root远程访问:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123123' WITH GRANT OPTION;

  1. WITH GRANT OPTION 表示该用户可以将自己的权限授权给别人
  2. 如果只授予部分权限,其中 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密码:

  1. systemctl stop mariadb.service
  2. mysqld_safe --skip-grant-tables
  3. mysql -u root
    1. update mysql.user set password=PASSWORD('newpassword') where User='root’;
    2. flush privileges;
  4. systemctl restart mariadb.service

事务

MySQL按照标准SQL定义了4种隔离级别,较低的隔离级别,能带来更高的并发和更低的系统开销。

  1. 未提交读(READ-UNCOMMITTED)

    • 可以读到未提交的修改记录
  2. 读已提交(READ-COMMITTED)
    • 只要提交的修改记录(包括其他的事务)都可以读到
    • 基于MVCC并发控制
  3. 可重复读(REPEATABLE-READ)
    • 在事务开始第一次读取后,其他事务可修改读到的数据,但读到的数据不会被修改(幻读情况下会新增和减少)
    • 基于MVCC并发控制
  4. 串行读(SERIALIZABLE)
    • 事务开始后发生对数据的操作(即使发生读操作),其他事务都不能修改数据
    • 基于锁控制:实际上串行读在RR级别上隐式加gap间隙共享锁:select ... for update

备注:

  1. set tx_isolation='READ-UNCOMMITTED'; 调整当前 session 隔离级别
  2. select @@tx_isolation 查看当前 session 隔离级别
  3. show processlist; 查看 mysql 连接状态

在4种隔离级别中又分别存在不同的读问题:

  1. 脏读(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; -- 会读到
  2. 不可重复读(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; -- 会读到
  3. 幻读(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 发生幻读,不能支持该业务执行
  4. 锁读(lock reads)
    • 在 SERIALIZABLE 级别会出现读的数据无法修改情况
    T1:select * from users where id = 3;
    T2:update `users` set `name` = 'baz' where `id` = 3; -- 执行失败,由于 Id = 3 的数据被锁

注意:

  1. 在同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条语句的时候,会创建1个readview。
  2. 将行数据的当前事务TRID 与 readview中的事务RVID 比较
    1. TRID < 所有的 RVID:可见(之前的事务创建)
    2. TRID > 所有的 RVID:不可见(新事务创建)
    3. TRID 在 RVID 中存在:不可见(活动的事务创建)
    4. TRID 在 RVID 中不存在:可见(内存中commit或自己创建)
    5. 当数据不可见时,会从数据的回滚指针获取数据重新判断一遍
  3. RC 和 RR的区别:
    1. RR 在事务开始只创建1次 readview
    2. RC 在事务每次执行语句都会创建 readview

事务提交过程及日志变化:

  1. 用 排他锁 锁定该行
  2. 记录 redo buffer
  3. copy 数据到 undo buffer
  4. 内存中修改数据 填写隐藏字段 事务Id 和 回滚指针

commit:

  1. redo log 文件持久化(innodb_flush_log_at_trx_commit)
  2. bin log 文件持久化(sync_binlog)(这一步完成能确保故障恢复)
  3. innodb引擎 commit(数据持久化,undo log)

注意:

  1. redo log 文件并不一定在commit时才做持久化

    1. Master Thread 每秒执行一次
    2. 每个事务提交时
    3. 当重做日志缓存可用空间 少于一半时
  2. redo log 是连续的一段存储空间,而修改的数据很可能是随机的区域
  3. undo log 并非在事务提交完立即释放
    1. 提交后放入待清理区域,由purge线程判断是否仍有其他事务在使用,来决定是否删除。
    2. 默认undo log 存储在 idb 表空间中,在 MariaDB 10.0(MySQL 5.7)后通过innodb_undo_directory 、innodb_undo_logs 、innodb_undo_tablespaces 可配置独立文件

主从复制

主从复制能提供水平扩展 数据备份 数据分析 高可用性等,故开启主从复制越来越必要。

复制

MariaDB 主从复制工作3步:

  1. 主库的数据更改记录到 binlog 中
  2. 从库将主库的日志 复制到 relaylog 中
    1. 从库使用 IO 线程请求主库
    2. 主库使用 dump 线程读取 binlog 传给
  3. 备库 SQL 线程读取 relaylog 事件,重放到数据库。

配置复制:

  1. 在主库和从库创建复制账号

    1. GRANT REPLICATION SLAVE, REPLICATION CLIENT ON . TO repl@'10.0.0.%' IDENTIFIED BY 'p4ssword';
  2. 配置主库和从库
    1. 配置主服务器:

      [mysqld]
      log_bin = mysql-bin
      server_id = 1 # 唯一,可以用IP地址的末几位
    2. 从服务器:

      [mysqld]
      log_bin = mysql-bin
      server_id = 2
      log_slave_updates = 1 # 重放同时写到binlog
      relay_log = /var/lib/mysql/mysql-relay-bin
  3. 从库启动复制
    1. MariaDB > CHANGE MASTER TO MASTER_HOST='server1',

      -> MASTER_USER='repl',

      -> MASTER_PASSWORD='p4ssword',

      -> MASTER_LOG_FILE='mysql-bin.000001',

      -> MASTER_LOG_POS=0;
    2. MariaDB > START SLAVE;
    3. MariaDB > SHOW SLAVE STATUS\G

注意:

  1. 要填写的复制的POSITION,可以通过 SHOW MASTER STATUS\G 查看
  2. 启用复制功能不会给服务器太多的开销。(主要是开启 binlog 和 sync_binlog=1 fsync的开销)
  3. 如果复制配置有问题,可以重置配置信息:stop slave; reset slave;

半同步复制:

默认复制是单向异步的,也支持半同步复制功能(MariaDB 10.3 后内置不需要单独安装插件)。

  1. 主库:

    set global rpl_semi_sync_master_enabled = 1;

    set global rpl_semi_sync_master_wait_point = AFTER_SYNC;
  2. 从库:

    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. 半同步复制是在事务提交时,等待至少1个从库接收并写到relay log才返回给客户端(Wait Slave ACK)。
  2. 半同步复制提高数据安全性,但也造成一定的延迟(最少是1次tcp/ip返还的时间)。
  3. 半同步复制默认AFTER_COMMIT是在bin log持久化及存储引擎提交后再等待从库接收写到relay log,通过rpl_semi_sync_master_wait_point配置为AFTER_SYNC,可以将从库复制操作改到主库存储引擎提交之前。

相当于有异步复制、半同步复制还有个全同步复制,代表为 mysql-cluster性能太差,需要等待所有slave都同步才commit成功(性能太差)

注意:

  1. 半同步复制数据一致性并不能100%保证,在非常极端情况下,AFTER_SYNC会出现从库数据多的情况,AFTER_COMMIT会出现从库数据丢失的情况。
  2. AFTER_SYNC 可以让存储引擎commit支持group commit。所以性能安全性都比AFTER_COMMIT好

GTID

从MariaDB 10.0.2开始,GTID会自动启用,在 binlog 中的每个事件组(事务)都会先记录1个GTID。

全局事务ID(简称GTID)由三个用短划线“ - ”分隔的数字组成。例如:0-1-10

  1. 第一个数字0是域ID,它特定于全局事务ID(以下更多内容)。它是一个32位无符号整数。
  2. 第二个数字是服务器ID,与旧式复制中使用的相同。它是一个32位无符号整数。
  3. 第三个数字是序列号。这是一个64位无符号整数,对于登录到binlog中的每个新事件组,它会单调递增。

为什么要使用GTID:

  1. 以前复制需要确定 binlog 文件名+偏移量。使用GTID则会自动确定。
  2. 以前通过 relaylog 文件记录复制进度,且和数据同步是独立进行。使用GTID,将会在数据更新的事务中一起更新状态(存在mysql.gtid_slave_pos)
  3. 更适合MHA时failover。

如何配置:

CHANGE MASTER TO master_use_gtid = { slave_pos | current_pos | no }

  1. current_pos:当前服务器最后1条binlog命令的gtid记录
  2. 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。

注意:

  1. MariaDB和MySQL具有不同的GTID实现,并且它们彼此不兼容。
  2. 完成复制的必要条件主库开启 binlog 日志,相当于开启主库的GTID。从库及时不开启 binlog, slave_pos 也会更新,但自执行的SQL不会影响current_pos。
  3. 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 没有任何关系。

配置步骤:

  1. 配置
    [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
  2. 引导新集群

    $ galera_new_cluster(Systemd推荐)
  3. 在多台服务器上开启mysql服务

    $ service mariadb start

注意:

  1. 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 之事务、复制、集群的更多相关文章

  1. Mariadb之半同步复制集群配置

    首先我们来了解下在mariadb/mysql数据库主从复制集群中什么是同步,什么是异步,什么是半同步:所谓同步就是指主节点发生写操作事件,它不会立刻返回,而是等到从节点接收到主节点发送过来的写操作事件 ...

  2. Redis高可用复制集群实现

    redis简单介绍 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库.Redis 与其他 key - value 缓存产品有以下三个特点: 支持数据的持久化,可以将 ...

  3. MHA实现mysql高可用复制集群

    MHA简述 MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件.在My ...

  4. Java应用服务器之tomcat会话复制集群配置

    会话是识别用户,跟踪用户访问行为的一个手段,通过cookie(存在客户端)或session(存在服务端)来判断本次请求是那个客户端发送过来:常用的会话保持有绑定会话,就是前边我们聊的在代理上通过算法或 ...

  5. 使用 Bitnami PostgreSQL Docker 镜像快速设置流复制集群

    bitnami-docker-postgresql 仓库 源码:bitnami-docker-postgresql https://github.com/bitnami/bitnami-docker- ...

  6. lcn 分布式事务协调者集群原理

    lcn集群原理图: 1.实现原理: 1.1 LCN获取tm协调者注册地址 1. LCN客户端项目启动的时候,首先会注册到事务协调者中去,然后读取配置文件tm事务协调者的注册地址. 2. 向该事务协调者 ...

  7. 【MySQL】MySQL-主从复制-集群方案-数据一致性问题解决方案 && MySQL备份的各种姿势

    1.写性能如何保证:分库分表 2.读性能如何保证:主从结构,实时备份 3.一致性问题怎么解决: 3.1.微博案例:Redis缓存,热数据查询走Redis,主从的延迟通过Redis消除 3.2.支付宝的 ...

  8. MongoDB搭建ReplSet复制集群

    MongoDB的复制集是一个主从复制模式 又具有故障转移的集群,任何成员都有可能是master,当master挂掉用会很快的重新选举一个节点来充当master. 复制集中的组成主要成员 Primary ...

  9. mysql组复制集群简介

    mysql组复制集群拓扑: 环境: centos6.5 mysql5.7.19 一.组复制搭建: 配置hosts文件 再三台服务器上分别启动一个mysql实例,共三个. 参考配置文件如下: serve ...

  10. 在 TKE 中使用 Velero 迁移复制集群资源

    概述 Velero(以前称为Heptio Ark)是一个开源工具,可以安全地备份和还原,执行灾难恢复以及迁移 Kubernetes 群集资源和持久卷,可以在 TKE 集群或自建 Kubernetes ...

随机推荐

  1. CSS| 颜色名

    CSS 颜色名 所有浏览器都支持的颜色名. HTML 和 CSS 颜色规范中定义了 147 中颜色名(17 种标准颜色加 130 种其他颜色).下面的表格中列出了所有这些颜色,以及它们的十六进制值. ...

  2. iftop – 实时Linux网络带宽监控工具

    在本文中,我们提出了另一个称为Interface TOP (IFTOP)的优秀程序, 它是一个基于实时控制台的网络带宽监控工具. 它将显示接口上网络活动的快速概览. Iftop 平均每 2,10 和4 ...

  3. 高通Audio中ASOC的machine驱动(一)

    ASoC被分为Machine.Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的代码,再次引用上一节的内容:Machin ...

  4. 【转载】sql注入之入门

    原文在:https://smelond.com MySql基础语法 mysql无非就是增删改查 mysql数据库结构: 数据库 test,test1 表名 admin,manage 数据 id,use ...

  5. LabVIEW TCP/IP 断开重连问题

    LabVIEW的TCP/IP函数库非常好用,但是不恰当地设置打开连接结点的参数将带来一些问题,麻烦.如下图的打开连接的参数设置: 上图中指定了本地的端口,会发生这样的情况.当我们关闭应用程序之后,连接 ...

  6. Qt在控件未显示时如何获取正确的控件尺寸

    因为打算全屏显示一个对话框,而对话框内有几个QLabel的尺寸要在确定QLabel可用的最大尺寸后,再根据内容调整一次,所以在对话框构造函数内就想确定QLabel的最大尺寸,但因为QWidget::u ...

  7. MySQL主从复制异步原理以及搭建

    MySQL主从复制的原理: 1.首先,MySQL主库在事务提交时会把数据变更作为时间events记录在二进制日志文件binlog中:MySQL主库上的sync_binlog参数控制Binlog日志以什 ...

  8. Java的数组堆溢出问题

    在写测试方法的时候,生成了一个数组,之后报了堆溢出错误,这样的报错一般来说只要有一些JVM的基础都知道要用-Xmx.-Xms来开更大的堆,接下来看看我碰到的一个堆溢出的问题 在测试代码中开了一个500 ...

  9. 如何安装Firebug

    Firebug是firefox下的一个插件,能够调试所有网站语言,如Html,Css等,但FireBug最吸引我的就是javascript调试功能,使用起来非常方便,而且在各种浏览器下都能使用(IE, ...

  10. Atcoder 水题选做

    为什么是水题选做呢?因为我只会水题啊 ( 为什么是$Atcoder$呢?因为暑假学长来讲课的时候讲了三件事:不要用洛谷,不要用dev-c++,不要用单步调试.$bzoj$太难了,$Topcoder$整 ...