MySQL5.7学习笔记

本文基于MySQL 5.7记录

一、安装

1、二进制安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 创建mysql相关的组和用户
groupadd mysql
useradd -r -g mysql -s /bin/false mysql
# 下载二进制包
cd /usr/local/
wget --no-check-certificate https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz
# 解压
tar xvzf mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz
# 将目录移动到/usr/local/mysql
ln -s mysql-5.7.24-linux-glibc2.12-x86_64 /usr/local/mysql
# 创建数据库数据目录
mkdir -p /path/to/mysql_data_dir
chown -R mysql:mysql /path/to/mysql_data_dir
# 使用叶金荣的配置生成工具创建my.cnf文件放在/etc/my.cnf
# http://imysql.com/my-cnf-wizard.html
chmod a+r /etc/my.cnf
chown mysql:mysql /etc/my.cnf
/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --initialize --user=mysql --basedir=/usr/local/mysql/ --datadir=/mysql_data
/usr/local/mysql/bin/mysql_ssl_rsa_setup --datadir=/mysql_data
# 查看error.log文件里面的root密码
grep password error.log | awk '{print$NF}'
# 启动MySQL
mysqld_safe --user=mysql &

2、rpm/deb软件源安装

以CentOS7为例

1
2
3
4
5
6
7
8
9
10
# 获取MySQL软件源
yum install -y https://dev.mysql.com/get/mysql57-community-release-el7-1.noarch.rpm
# 更新YUM缓存
yum makecache
# 安装MySQL5.7
yum install mysql-community-server
# 启动MySQL
systemctl start mysqld.service
# 获取ROOT密码
grep 'temporary password' /var/log/mysqld.log

3、源码安装

以CentOS7为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 安装编译环境
yum -y install make gcc-c++ cmake bison-devel ncurses-devel
# 下载MySQL源代码
wget --no-check-certificate https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-boost-5.7.24.tar.gz
# 创建MySQL相关的组和用户
groupadd mysql
useradd -r -g mysql -s /bin/false mysql
# 创建MySQL相关文件夹
mkdir -p /app/mysql
mkdir -p /app/data
mkdir -p /app/etc
mkdir -p /app/log
chown -R mysql:mysql /app
# 解压源代码
tar xvzf mysql-boost-5.7.24.tar.gz
# 创建cmake编译目录
mkdir build
cd build
# 使用CMake生成makefile
cmake -DCMAKE_INSTALL_PREFIX=/app/mysql/ \
-DMYSQL_USER=mysql \
-DMYSQL_TCP_PORT=3306 \
-DMYSQL_UNIX_ADDR=/app/data/mysql.sock \
-DDEFAULT_CHARSET=utf8mb4 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DEXTRA_CHARSETS=all \
-DWITH_READLINE=1 \
-DWITH_SYSTEMD=1 \
-DWITH_BOOST=/root/mysql-5.7.24/boost/boost_1_59_0/ \
/root/mysql-5.7.24/
# 编译安装
make && make install
# 使用叶金荣MySQL配置生成工具生成my.cnf放在/app/etc/my.cnf
# http://imysql.com/my-cnf-wizard.html
chown mysql:mysql /app/etc/my.cnf
# 初始化MySQL数据库
mysqld --initialize --defaults-file=/app/etc/my.cnf --user=mysql --basedir=/app/mysql/ --datadir=/app/data/
mysql_ssl_rsa_setup --datadir=/app/data/
# 启动MySQL数据库
mysqld_safe --defaults-file=/app/etc/my.cnf --user=mysql &
# 获取MySQL ROOT密码
grep password error.log | awk '{print$NF}'

4、安装后设定

4.1、安全设置

1
mysql_secure_installation

4.2、建议设置

关闭主机名反向解析,在配置文件的[mysqld]里面添加skip_name_resolve = 1

1
2
3
4
vi /etc/my.cnf
[mysqld]
...
skip_name_resolve = 1

5、数据库连接

5.1、mysql命令行客户端

1
mysql -uroot -ppassword -h127.0.0.1 -P3306 -D db1

5.2、MySQL Benchmark图形客户端

官方网站下载页面

6、获取MySQL编译的参数

在MySQL目录的docs/INFO_BIN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# 例如安装目录为/usr/local/mysql
# MySQL官方YUM源安装的路径为/usr/share/doc/packages/MySQL-server
cat /usr/local/bin/mysql/docs/INFO_BIN
===== Information about the build process: =====
Build was run at 2018-10-04 08:26:03 on host 'vitro45'

Build was done on Linux-3.8.13-16.2.1.el6uek.x86_64 using x86_64
Build was done using cmake 2.8.12

===== Compiler flags used (from the 'sql/' subdirectory): =====
# compile C with /usr/bin/cc
# compile CXX with /usr/bin/c++
C_FLAGS = -fPIC -Wall -Wextra -Wformat-security -Wvla -Wwrite-strings -Wdeclaration-after-statement -O3 -g -fabi-version=2 -fno-omit-frame-pointer -fno-strict-aliasing -DDBUG_OFF -I/export/home/pb2/build/sb_0-30854123-1538633287.09/release/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/extra/rapidjson/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/release/libbinlogevents/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/libbinlogevents/export -isystem /export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/zlib -isystem /export/home/pb2/build/sb_0-30854123-1538633287.09/release/zlib -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/sql/conn_handler -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/libbinlogevents/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/sql -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/sql/auth -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/regex -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/extra/yassl/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/extra/yassl/taocrypt/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/release/sql -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/extra/lz4 -isystem /export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/include/boost_1_59_0/patches -isystem /usr/global/share/boost_1_59_0 -DHAVE_YASSL -DYASSL_PREFIX -DHAVE_OPENSSL -DMULTI_THREADED
C_DEFINES = -DHAVE_CONFIG_H -DHAVE_LIBEVENT1 -DHAVE_REPLICATION -DMYSQL_SERVER -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
CXX_FLAGS = -fPIC -Wall -Wextra -Wformat-security -Wvla -Woverloaded-virtual -Wno-unused-parameter -O3 -g -fabi-version=2 -fno-omit-frame-pointer -fno-strict-aliasing -DDBUG_OFF -I/export/home/pb2/build/sb_0-30854123-1538633287.09/release/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/extra/rapidjson/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/release/libbinlogevents/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/libbinlogevents/export -isystem /export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/zlib -isystem /export/home/pb2/build/sb_0-30854123-1538633287.09/release/zlib -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/sql/conn_handler -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/libbinlogevents/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/sql -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/sql/auth -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/regex -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/extra/yassl/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/extra/yassl/taocrypt/include -I/export/home/pb2/build/sb_0-30854123-1538633287.09/release/sql -I/export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/extra/lz4 -isystem /export/home/pb2/build/sb_0-30854123-1538633287.09/mysql-5.7.24/include/boost_1_59_0/patches -isystem /usr/global/share/boost_1_59_0 -DHAVE_YASSL -DYASSL_PREFIX -DHAVE_OPENSSL -DMULTI_THREADED
CXX_DEFINES = -DHAVE_CONFIG_H -DHAVE_LIBEVENT1 -DHAVE_REPLICATION -DMYSQL_SERVER -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE

Pointer size: 8

===== Feature flags used: =====
-- Cache values
BOOST_INCLUDE_DIR:PATH=/usr/global/share/boost_1_59_0
BUILD_TESTING:BOOL=ON
BUNDLE_MECAB:BOOL=ON
CMAKE_BACKWARDS_COMPATIBILITY:STRING=2.4
CMAKE_BUILD_TYPE:STRING=RelWithDebInfo
CMAKE_INSTALL_PREFIX:PATH=/usr/local/mysql
COMMUNITY_BUILD:BOOL=ON
CTAGS_EXECUTABLE:FILEPATH=/usr/bin/ctags
DEB_CHANGELOG_TIMESTAMP:STRING=Thu, 04 Oct 2018 08:14:16 +0200
DEB_CODENAME:STRING=n/a
DOWNLOAD_BOOST:BOOL=OFF
DOWNLOAD_BOOST_TIMEOUT:STRING=600
ENABLED_PROFILING:BOOL=ON
ENABLE_DOWNLOADS:BOOL=OFF
ENABLE_GCOV:BOOL=OFF
ENABLE_GPROF:BOOL=OFF
ENABLE_MEMCACHED_SASL:BOOL=OFF
ENABLE_MEMCACHED_SASL_PWDB:BOOL=OFF
EXECUTABLE_OUTPUT_PATH:PATH=
FEATURE_SET:STRING=community
INSTALL_LAYOUT:STRING=STANDALONE
INSTALL_PKGCONFIGDIR:PATH=
LIBRARY_OUTPUT_PATH:PATH=
LOCAL_BOOST_DIR:FILEPATH=/usr/global/share/boost_1_59_0
LOCAL_BOOST_ZIP:FILEPATH=/usr/global/share/boost_1_59_0.tar.gz
LOCAL_GMOCK_ZIP:FILEPATH=/usr/global/share/googletest-release-1.8.0.zip
MECAB_INCLUDE_DIR:PATH=/export/home/pb2/build/sb_0-30854123-1538633287.09/mecab-0.996-el6-x86-64bit/include
MECAB_LIBRARY:FILEPATH=/export/home/pb2/build/sb_0-30854123-1538633287.09/mecab-0.996-el6-x86-64bit/lib/libmecab.a
MERGE_UNITTESTS:BOOL=ON
MUTEXTYPE:STRING=event
MYSQL_DATADIR:PATH=/usr/local/mysql/data
MYSQL_KEYRINGDIR:PATH=/usr/local/mysql/keyring
MYSQL_MAINTAINER_MODE:BOOL=OFF
OPTIMIZER_TRACE:BOOL=ON
REPRODUCIBLE_BUILD:BOOL=OFF
RPC_INCLUDE_DIR:PATH=/usr/include
SASL_SYSTEM_LIBRARY:FILEPATH=/usr/lib64/libsasl2.so
TMPDIR:PATH=P_tmpdir
WITH_ARCHIVE_STORAGE_ENGINE:BOOL=ON
WITH_ASAN:BOOL=OFF
WITH_ASAN_SCOPE:BOOL=OFF
WITH_BLACKHOLE_STORAGE_ENGINE:BOOL=ON
WITH_BOOST:PATH=/usr/global/share
WITH_CLIENT_PROTOCOL_TRACING:BOOL=ON
WITH_DEBUG:BOOL=OFF
WITH_DEFAULT_COMPILER_OPTIONS:BOOL=ON
WITH_DEFAULT_FEATURE_SET:BOOL=ON
WITH_EDITLINE:STRING=bundled
WITH_EMBEDDED_SERVER:BOOL=ON
WITH_EMBEDDED_SHARED_LIBRARY:BOOL=OFF
WITH_EXTRA_CHARSETS:STRING=all
WITH_FEDERATED_STORAGE_ENGINE:BOOL=ON
WITH_INNODB_EXTRA_DEBUG:BOOL=OFF
WITH_INNODB_MEMCACHED:BOOL=1
WITH_LIBEVENT:STRING=bundled
WITH_LIBWRAP:BOOL=OFF
WITH_LZ4:STRING=bundled
WITH_MECAB:STRING=/export/home/pb2/build/sb_0-30854123-1538633287.09/mecab-0.996-el6-x86-64bit
WITH_MECAB_PATH:PATH=/export/home/pb2/build/sb_0-30854123-1538633287.09/mecab-0.996-el6-x86-64bit
WITH_MSAN:BOOL=OFF
WITH_NGRAM_PARSER:BOOL=ON
WITH_NUMA:BOOL=ON
WITH_PARTITION_STORAGE_ENGINE:BOOL=ON
WITH_PIC:BOOL=ON
WITH_RAPID:BOOL=ON
WITH_SASL:STRING=system
WITH_SSL:STRING=bundled
WITH_SYSTEMD:BOOL=OFF
WITH_TEST_TRACE_PLUGIN:BOOL=OFF
WITH_UBSAN:BOOL=OFF
WITH_UNIT_TESTS:BOOL=ON
WITH_VALGRIND:BOOL=OFF
WITH_ZLIB:STRING=bundled
XPLUGIN_LOG_PROTOBUF:STRING=1

===== EOF =====

二、配置数据库

1、配置文件路径

文件优先级,同一个参数以最后一个为准,启动时可指定–default-file=/path/to/my.cnf

  • /etc/my.cnf
  • /etc/mysql/my.cnf
  • $MYSQL_HOME/my.cnf
  • –default-extra-file=/path/to/*.cnf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    [client]
    port = 3306
    socket = /data/mysql/mysql.sock
    [mysql]
    prompt="\u@mysqldb \R:\m:\s [\d]> "
    no-auto-rehash
    [mysqld]
    user = mysql
    port = 3306
    basedir = /usr/local/mysql
    datadir = /data/mysql/
    socket = /data/mysql/mysql.sock
    pid-file = mysqldb.pid
    character-set-server = utf8mb4
    skip_name_resolve = 1
    open_files_limit = 65535
    back_log = 1024
    max_connections = 512
    max_connect_errors = 1000000
    table_open_cache = 1024
    table_definition_cache = 1024
    table_open_cache_instances = 64
    thread_stack = 512K
    external-locking = FALSE
    max_allowed_packet = 32M
    sort_buffer_size = 16M
    join_buffer_size = 16M
    thread_cache_size = 768
    interactive_timeout = 600
    wait_timeout = 600
    tmp_table_size = 96M
    max_heap_table_size = 96M
    slow_query_log = 1
    slow_query_log_file = /data/mysql/slow.log
    log-error = /data/mysql/error.log
    long_query_time = 0.1
    log_queries_not_using_indexes =1
    log_throttle_queries_not_using_indexes = 60
    min_examined_row_limit = 100
    log_slow_admin_statements = 1
    log_slow_slave_statements = 1
    server-id = 3306
    log-bin = /data/mysql/mybinlog
    sync_binlog = 1
    binlog_cache_size = 4M
    max_binlog_cache_size = 2G
    max_binlog_size = 1G
    expire_logs_days = 7
    master_info_repository = TABLE
    relay_log_info_repository = TABLE
    gtid_mode = on
    enforce_gtid_consistency = 1
    log_slave_updates
    slave-rows-search-algorithms = 'INDEX_SCAN,HASH_SCAN'
    binlog_format = row
    binlog_checksum = 1
    relay_log_recovery = 1
    relay-log-purge = 1
    key_buffer_size = 32M
    read_buffer_size = 8M
    read_rnd_buffer_size = 16M
    bulk_insert_buffer_size = 64M
    myisam_sort_buffer_size = 128M
    myisam_max_sort_file_size = 10G
    myisam_repair_threads = 1
    lock_wait_timeout = 3600
    explicit_defaults_for_timestamp = 1
    innodb_thread_concurrency = 0
    innodb_sync_spin_loops = 100
    innodb_spin_wait_delay = 30
    transaction_isolation = REPEATABLE-READ
    #innodb_additional_mem_pool_size = 16M
    innodb_buffer_pool_size = 45875M
    innodb_buffer_pool_instances = 4
    innodb_buffer_pool_load_at_startup = 1
    innodb_buffer_pool_dump_at_shutdown = 1
    innodb_data_file_path = ibdata1:1G:autoextend
    innodb_flush_log_at_trx_commit = 1
    innodb_log_buffer_size = 32M
    innodb_log_file_size = 2G
    innodb_log_files_in_group = 2
    innodb_max_undo_log_size = 2G
    innodb_undo_directory = undolog
    innodb_undo_tablespaces = 8
    # 根据您的服务器IOPS能力适当调整
    # 一般配普通SSD盘的话,可以调整到 10000 - 20000
    # 配置高端PCIe SSD卡的话,则可以调整的更高,比如 50000 - 80000
    innodb_io_capacity = 4000
    innodb_io_capacity_max = 8000
    innodb_flush_neighbors = 0
    innodb_write_io_threads = 8
    innodb_read_io_threads = 8
    innodb_purge_threads = 4
    innodb_page_cleaners = 4
    innodb_open_files = 65535
    innodb_max_dirty_pages_pct = 50
    innodb_flush_method = O_DIRECT
    innodb_lru_scan_depth = 4000
    innodb_checksum_algorithm = crc32
    innodb_lock_wait_timeout = 10
    innodb_rollback_on_timeout = 1
    innodb_print_all_deadlocks = 1
    innodb_file_per_table = 1
    innodb_online_alter_log_max_size = 2G
    internal_tmp_disk_storage_engine = InnoDB
    innodb_stats_on_metadata = 0
    # some var for MySQL 8
    log_error_verbosity = 3
    innodb_print_ddl_logs = 1
    binlog_expire_logs_seconds = 604800
    #innodb_dedicated_server = 0
    innodb_status_file = 1
    # 注意: 开启 innodb_status_output & innodb_status_output_locks 后, 可能会导致log-error文件增长较快
    innodb_status_output = 0
    innodb_status_output_locks = 0
    #performance_schema
    performance_schema = 1
    performance_schema_instrument = '%=on'
    #innodb monitor
    innodb_monitor_enable="module_innodb"
    innodb_monitor_enable="module_server"
    innodb_monitor_enable="module_dml"
    innodb_monitor_enable="module_ddl"
    innodb_monitor_enable="module_trx"
    innodb_monitor_enable="module_os"
    innodb_monitor_enable="module_purge"
    innodb_monitor_enable="module_log"
    innodb_monitor_enable="module_lock"
    innodb_monitor_enable="module_buffer"
    innodb_monitor_enable="module_index"
    innodb_monitor_enable="module_ibuf_system"
    innodb_monitor_enable="module_buffer_page"
    innodb_monitor_enable="module_adaptive_hash"
    [mysqld_safe]
    [mysqld_multi]
    [mysqldump]
    quick
    max_allowed_packet = 32M
    [server]

2、数据库变量

2.1、查看数据库全局变量

1
mysql> show global variables;

2.2、查看数据库会话变量

1
mysql> show session variables;

3、开启MySQL SSL功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 使用MySQL自带工具生成证书
mysql_ssl_rsa_setup --datadir=MYSQL_DATA_DIR
# 证书默认存放data-dir
ll /mysql_data/*pem
-rw------- 1 root root 1675 Oct 30 13:43 /mysql_data/ca-key.pem
-rw-r--r-- 1 root root 1107 Oct 30 13:43 /mysql_data/ca.pem
-rw-r--r-- 1 root root 1107 Oct 30 13:43 /mysql_data/client-cert.pem
-rw------- 1 root root 1679 Oct 30 13:43 /mysql_data/client-key.pem
-rw------- 1 root root 1675 Oct 30 13:43 /mysql_data/private_key.pem
-rw-r--r-- 1 root root 451 Oct 30 13:43 /mysql_data/public_key.pem
-rw-r--r-- 1 root root 1107 Oct 30 13:43 /mysql_data/server-cert.pem
-rw------- 1 root root 1675 Oct 30 13:43 /mysql_data/server-key.pem
# 配置文件指明SSL证书路径
[mysqld]
ssl-ca=/mysql_data/ca.pem
ssl-cert=/mysql_data/server-cert.pem
ssl-key=/mysql_data/server-key.pem
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 查看数据库SSL变量
mysql> show global variables like '%ssl%';
+---------------+-----------------------------+
| Variable_name | Value |
+---------------+-----------------------------+
| have_openssl | DISABLED |
| have_ssl | DISABLED |
| ssl_ca | /mysql_data/ca.pem |
| ssl_capath | |
| ssl_cert | /mysql_data/server-cert.pem |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | /mysql_data/server-key.pem |
+---------------+-----------------------------+
# 强制用户使用SSL登录
mysql> alter user 'username'@'host' require ssl;
# 创建用户时要求使用SSL登录
mysql> grant all privileges on dbname.tablename to 'username'@'host' identified by 'password' require ssl;
# 取消强制用户使用SSL登录
mysql> alter user 'username'@'host' require none;
1
2
3
4
5
# 使用SSL证书登录数据库
mysql -uUSERNAME -pPASSWORD -hHOSTNAME \
--ssl-ca=ca.pem \
--ssl-cert=client-cert.pem \
--ssl-key=client-key.pem

三、事务隔离

一组原子性SQL操作,或者是独立的工作单元。

1、ACID

1.1、Atomicity原子性

整个事务中的所有操作要么全部执行成功,要么失败后完全回滚。

1.2、Consistency一致性

数据库总是从一个一致性状态转换到另一个一致性状态。

1.3、Isolation隔离性

一个事务的操作在提交之前,不能被其他会话所见。

可分为多个隔离级别

1.4、Durability永久性

事务一旦提交,操作结果将永久保存到数据库中。

2、锁机制

2.1、写锁

其他事务不能读取,也不能写。

2.2、读锁

其他事务可以读,但不能写。

3、脏读

脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

4、不可重复读

是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

5、幻读

指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

6、事务隔离级别

默认是REPEATEABLE READ 可重复读

6.1、READ UNCOMMITED读未提交

事务间完全不隔离,会产生脏读,可以读取未提交的记录。

6.2、READ COMMITED读已提交

仅能读取到已提交的记录,不会脏读,会不可重复读,会幻读。

6.3、REPEATABLE READ可重复读

每次读取的结果集都相同,而不管其他事务有没有提交,但是无法阻止其他事务插入数据,因此可能导致幻读。

6.4、SERIALIZABILE可串行化

最严格的锁,在事务完成前,其他事务无法对数据对象进行写操作。并行性能最差。

四、数据库日志

1、查询日志 query log

记录查询操作,产生额外IO消耗,一般不打开。

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> show global variables like '%general%';
+------------------+---------------------------+
| Variable_name | Value |
+------------------+---------------------------+
| general_log | OFF |
| general_log_file | /var/log/hostname.log |
+------------------+---------------------------+
mysql> show global variables like 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output | FILE |
+---------------+-------+

2、慢查询日志 slow query log

执行时长超过指定时长的查询操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> show global variables like 'long_query_time';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 0.100000 |
+-----------------+----------+
> show global variables like '%slow%';
+---------------------------+-------------------------+
| Variable_name | Value |
+---------------------------+-------------------------+
| log_slow_admin_statements | ON |
| log_slow_slave_statements | ON |
| slow_launch_time | 2 |
| slow_query_log | ON |
| slow_query_log_file | /var/log/mysql/slow.log |
+---------------------------+-------------------------+

3、错误日志 error log

记录MySQL启动关闭过程输出的日志

记录MySQL运行过程中产生的错误日志

记录event scheduler运行event时产生的日志

记录主从复制架构中从服务器上启动从服务器线程时产生的日志

1
2
3
4
5
6
7
8
9
10
11
> show global variables like '%error%';
+---------------------+--------------------------+
| Variable_name | Value |
+---------------------+--------------------------+
| binlog_error_action | ABORT_SERVER |
| log_error | /var/log/mysql/error.log |
| log_error_verbosity | 3 |
| max_connect_errors | 1000000 |
| max_error_count | 64 |
| slave_skip_errors | OFF |
+---------------------+--------------------------+

4、二进制日志 binary log

4.1、介绍

记录对mysql数据更新或潜在发生更新的SQL语句,并以”事务”的形式保存在磁盘中。

用于通过“重放”日志生成数据副本。

4.2、日志记录内容

基于“语句”记录:statement

基于“行”记录:row

混合模式:mixed,由数据库自动判定

4.3、日志文件构成

日志文件:mysql-bin,二进制格式

索引文件:mysql-bin.index,文本格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
mysql > show global variables like '%bin%';
+--------------------------------------------+----------------------------+
| Variable_name | Value |
+--------------------------------------------+----------------------------+
| binlog_cache_size | 4194304 |
| binlog_checksum | CRC32 |
| binlog_direct_non_transactional_updates | OFF |
| binlog_error_action | ABORT_SERVER |
| binlog_format | ROW |
| binlog_group_commit_sync_delay | 0 |
| binlog_group_commit_sync_no_delay_count | 0 |
| binlog_gtid_simple_recovery | ON |
| binlog_max_flush_queue_time | 0 |
| binlog_order_commits | ON |
| binlog_row_image | FULL |
| binlog_rows_query_log_events | OFF |
| binlog_stmt_cache_size | 32768 |
| binlog_transaction_dependency_history_size | 25000 |
| binlog_transaction_dependency_tracking | COMMIT_ORDER |
| innodb_api_enable_binlog | OFF |
| innodb_locks_unsafe_for_binlog | OFF |
| log_bin | ON |
| log_bin_basename | /mysql_data/mybinlog |
| log_bin_index | /mysql_data/mybinlog.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| log_statements_unsafe_for_binlog | ON |
| max_binlog_cache_size | 2147483648 |
| max_binlog_size | 1073741824 |
| max_binlog_stmt_cache_size | 18446744073709547520 |
| sync_binlog | 1 |
+--------------------------------------------+----------------------------+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql > show binary logs;
+-----------------+-----------+
| Log_name | File_size |
+-----------------+-----------+
| mybinlog.000001 | 177 |
| mybinlog.000002 | 11841 |
+-----------------+-----------+
mysql > show master status;
+-----------------+----------+--------------+------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------+----------+--------------+------------------+-------------------------------------------+
| mybinlog.000002 | 11841 | | | 2c719e09-d6a4-11e8-b4f9-560000590d55:1-31 |
+-----------------+----------+--------------+------------------+-------------------------------------------+
mysql > show binlog events in 'mybinlog.000002' from 4 limit 1;
+-----------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+-----------------+-----+-------------+-----------+-------------+---------------------------------------+
| mybinlog.000002 | 4 | Format_desc | 3306 | 123 | Server ver: 5.7.24-log, Binlog ver: 4 |
+-----------------+-----+-------------+-----------+-------------+---------------------------------------+

4.4、mysqlbinlog工具读取二进制日志

基于时间点

1
mysqlbinlog -uroot -pxvnCv3Yz -hlocalhost -P3306 --start-datetime='2018-10-23 00:00:00' --stop-datetime='2018-10-24 13:00:00' -d myblog /mysql_data/mybinlog.000002

基于position

1
mysqlbinlog -uroot -pxvnCv3Yz -hlocalhost -P3306 --start-position=10613 --stop-position=11684 -d myblog /mysql_data/mybinlog.000002

4.5、二进制日志事件的格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# at 11305
#181024 11:38:30 server id 3306 end_log_pos 11684 CRC32 0xf0b28827 Query thread_id=32 exec
_time=0 error_code=0
SET TIMESTAMP=1540352310/*!*/;
CREATE TABLE `vote_record_memory` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(20) NOT NULL,
`vote_id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `index_user_id` (`user_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
/*!*/;

事件发生的日期和时间: 181024 11:38:30

事件发生的服务器标识: server id 3306

事件结束位置: end_log_pos 11684

事件类型: Query

事件发生时所在服务器执行此事件的线程ID: thread_id=32

语句的时间戳与写入二进制文件的时间差: exec_time=0

错误代码: error_code=0

事件内容

1
2
3
4
5
6
7
8
9
10
11
SET TIMESTAMP=1540352310/*!*/;
CREATE TABLE `vote_record_memory` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(20) NOT NULL,
`vote_id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `index_user_id` (`user_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
/*!*/;

GTID:Global Transaction ID;全局事务ID

5、中继日志 relay log

主从复制架构中,从服务器将主服务器的二进制日志事件拷贝到自己的中继日志。

6、事务日志 transaction log

由数据库引擎自行管理。

当有更新操作时,存储引擎只将数据在内存中的copy修改成更新后的值,但并不将数据的更新刷新的硬盘,只是将更新操作的行为记录到硬盘上的事务日志中。因为事务日志的记录是采用文件追加的方式,因此写日志的操作是磁盘上一小块区域内的顺序I/O,而不像随机I/O需要在磁盘的多个地方移动磁头。

因此事务日志的记录是非常快的。

事务日志由多个日志文件组组成,循环使用日志文件。

事务日志的大小需要根据实际情况设定。

6.1、重做日志redo log

用于记录修改后的数据,顺序记录,可以根据这个文件的记录内容重新恢复数据。

6.2、回滚日志undo log

用于存放被修改前的数据,回滚操作,实现事务一致性。

五、备份还原

1、为什么要备份

  • 灾难备份
  • 硬件故障
  • 软件故障
  • 自然灾害
  • 黑客攻击
  • 人为操作
  • 业务测试

2、注意事项

  • 能容忍丢失多少数据
  • 备份操作持锁时长
  • 备份负载
  • 恢复数据的时长
  • 需要恢复哪些数据
  • 备份的有效性
  • 备份恢复测试和演练
  • 生产数据和备份数据分开存放

3、备份类型

  • 热备:备份过程数据库可读可写
  • 温备:备份过程数据库可读不可写
  • 冷备:备份过程数据库不可读不可写
  • 全量备份:完整数据集
  • 增量备份:仅备份最近一次全备或者增备以来变化的数据
  • 差异备份:仅备份最近一次全备以来变化的数据
  • 物理备份:块级别备份,备份数据文件
  • 逻辑备份:从数据库导出数据,与存储引擎无关,可用于数据迁移

    4、备份内容

  • 数据
  • 二进制日志、InnoDB事务日志
  • 配置文件
  • 代码(存储过程、存储函数、触发器、事件调度器)

    5、逻辑备份工具

    Schema和数据存储在一个巨大的单个SQL语句文件

    5.1、mysqldump

MyISAM:备份库添加只读锁,直至备份完成

默认导出所有数据库的所有表
锁定方法(对InnoDB有效实现温备):
–lock-all-tables 锁定所有库的所有表
–log-tables 对于每个单独的数据库,在启动备份前锁定其所有表
InnoDB:支持热备、温备
–single-transaction 设置本次会话隔离级别为Repeatable Read,确保本次会话不会看到其他会话提交的数据,保证数据一致性

命令说明

1
2
3
4
5
6
# 备份指定数据库或者数据库中的表
mysqldump [options] db_name [table_name]
# 备份多个数据库
mysqldump [options] --database db1 [db2, db3]
# 备份所有数据库
mysqldump [options] --all-databases

命令示例

1
2
3
4
5
6
# 备份数据库db1,导出为db1.sql
mysqldump -uroot -ppassword -h127.0.0.1 -P3306 db1 > db1.sql
# 备份数据库db1的table1表,导出为table1.sql
mysqldump -uroot -ppassword -h127.0.0.1 -P3306 db1 table1 > table1.sql
# 备份数据库db1的table1和table2表,导出为table1_table2.sql
mysqldump -uroot -ppassword -h127.0.0.1 -P3306 db1 table1 table2 > table1_table2.sql

6、物理备份

6.1、xtrabackup

适用于InnoDB和XtraDB,一般使用innobackupex(xtrabackup的命令简化版)

官方网站下载地址

安装

1
2
3
4
5
6
# 下载xtrabackup二进制包
wget --no-check-certificate https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12/binary/tarball/percona-xtrabackup-2.4.12-Linux-x86_64.libgcrypt11.tar.gz
# 解压二进制包
tar xvzf percona-xtrabackup-2.4.12-Linux-x86_64.libgcrypt11.tar.gz.tar.gz
mv percona-xtrabackup-2.4.12-Linux-x86_64 /usr/local/
ln -sv /usr/local/percona-xtrabackup-2.4.12-Linux-x86_64 /usr/local/xtrabackup

命令说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 全量备份整个数据库(包括配置文件、二进制日志、重做日志、回滚日志、数据文件)
/usr/local/xtrabackup/bin/innobackupex --defaults-file=/etc/my.cnf --user=root --password=password --port=3306 BACKUP_DIR

# 增量备份整个数据库
/usr/local/xtrabackup/bin/innobackupex --defaults-file=/etc/my.cnf --user=root --password=password --host=localhost --port=3306 --incremental --incremental-basedir=/backup_dir/YYYY-MM-DD_HH-mm-ss/ /mysql_backup/

# 将增量备份的redo log合并到全量备份
/usr/local/xtrabackup/bin/innobackupex --apply-log --redo-only FULL_BACKUP_DIR
/usr/local/xtrabackup/bin/innobackupex --apply-log --redo-only FULL_BACKUP_DIR --incremental-dir=/INCREMENTAL_BACKUP_DIR/

# 恢复全量备份
/usr/local/xtrabackup/bin/innobackupex --defaults-file=/etc/my.cnf --copy-back FULL_BACKUP_DIR

# 从全量备份中“导出”表
# 需要在配置中启用innodb_file_per_table=1
# 此命令会为每一个InnoDB表创建一个.exp结尾的文件仅包含数据,不包含表结构
/usr/local/xtrabackup/bin/innobackupex --apply-log --export FULL_BACKUP_DIR

# 从全量备份中“导入”表
mysql> create table table_name (...) engine=InnoDB;
mysql> alter table db_name.table_name discard tablespaces;
# 将“导出”表的table_name.ibd和table_name文件拷贝到服务器数据目录,使用以下命令“导入”
mysql> alter table db_name.table_name import tablespaces;

6.2、其他备份工具

  • LVM快照

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 锁定所有表
    mysql > flush tables with read lock;
    # 记录二进制日志文件和事件位置
    mysql > flush logs;
    mysql -e 'show master status' > /path/to/file
    # 创建快照
    lvcreate -L # -s -p r -n NAME /dev/vg_name/lv_name
    # 释放锁
    mysql > unlock tables;
    # 挂载快照卷,执行数据备份
    # 备份完成删除快照卷

六、主从复制

1、主节点

dump thread:为每个Slave的IO Thread 启动一个dump线程,向其发送binary log events

2、从节点

IO Thread:从Master请求binary log events,并保存到中继日志

SQL Thread:从中继日志读取日志事件,在本地完成重放

3、特点

  • Mater和Slave之间是异步复制
  • 主从数据不一致的情况比较常见

4、复制架构

4.1、主从复制

4.1.1、主节点配置过程

启动二进制日志

为当前节点设置全局唯一的ID号

1
2
3
4
5
6
7
8
# 在my.cnf里面添加以下内容
[mysqld]
log-bin = master-binlog
innodb_file_per_table = 1
server-id = 1
sync_binlog = 1
innodb_flush_logs_at_trx_commit = 1
sync_master_info = 1

创建有复制权限的用户账号

1
2
mysql> grant replication slave,replication client on *.* to 'repuser'@'%' identified by 'password';
mysql> flush privileges;

4.1.2、从节点配置过程

启动中继日志

为当前节点设置全局唯一的ID号

设置为只读状态(不影响主从复制)

1
2
3
4
5
6
7
8
9
10
11
# 在my.cnf里面添加以下内容
[mysqld]
skip_slave_start = 1
relay-log = relay-log
relay-log = relay-log.index
server-id = 2
innodb_file_per_table = 1
skip_name_resolve = 1
read_only = 1
sync_relay_log = 1
sync_relay_log_info = 1

使用有复制权限的用户账号连接到主服务器,并启动复制线程

1
2
mysql> change master to master_host='master-node',master_user='repuser',master_password='password',master_port=3306,master_log_file='mater-log.003',master_log_pos=1111,master_connect_retry=10;
mysql> start slave [io_thread|sql_thread];

查看从状态信息

1
mysql> show slave status\G;

4.1.3、复制架构中应该注意的问题

限制从服务器只读

1
2
3
4
5
6
# 确保my.cnf配置以下选项
[mysqld]
read_only = 1
# read_only对拥有super权限用户无效
# 阻止所有用户,不影响主从复制
mysql> flush tables with read lock;

保证主从复制事务安全

主节点配置

1
2
3
4
5
6
7
8
[mysqld]
# 每次事务提交都写入binlog
sync_binlog = 1
# 如果启用了InnoDB,需要启用以下配置
# 每次事务提交时,log buffer 会被写入到日志文件并刷写到磁盘。
innodb_flush_logs_at_trx_commit = 1
# 每次事务提交都写入master.info,这样在崩溃的时候,最多丢失一个事务,但是会造成大量的磁盘IO
sync_master_info = 1

从节点

1
2
3
4
5
6
7
[mysqld]
# 手动启动slave
skip_slave_start = 1
# slave的IO线程每次接受到master发送过来的binlog日志都要写入到系统缓冲去,然后刷入relay log中继日志里面,这样在崩溃的时候,最多丢失一个事务,但是会造成大量的磁盘IO
sync_relay_log = 1
# slave的IO线程每次接受到master发送过来的binlog日志都要写入到系统缓冲去,然后刷入relay-log.info中继日志里面,这样在崩溃的时候,最多丢失一个事务,但是会造成大量的磁盘IO
sync_relay_log_info = 1

4.2、主主复制

4.2.1、注意事项

互为主从

容易数据不一致,慎用

自动增长ID

A节点使用奇数ID

1
2
3
[mysqld]
auto_increment_offset = 1
auto_increment_increment = 2

B节点使用偶数ID

1
2
3
[mysqld]
auto_increment_offset = 2
auto_increment_increment = 2

4.2.2、配置步骤

使用唯一的server_id

启动bin_log和relay_log

创建拥有复制权限的用户

定义自动增长ID字段数值范围为奇偶

均把对方指定为主节点,启动复制线程

4.3、半同步复制

跟主从复制类似

主节点会等待一个从节点写入完成再返回客户端写入成功

通过semisync插件提供半同步复制功能

1
2
3
4
5
6
# 二进制安装包
/usr/local/mysql/lib/plugin/semisync_master.so
/usr/local/mysql/lib/plugin/semisync_slave.so
# rpm安装包
/usr/lib64/mysql/plugin/semisync_master.so
/usr/lib64/mysql/plugin/semisync_slave.so

4.3.1、主节点

启动二进制日志

为当前节点设置全局唯一的ID号

1
2
3
4
5
6
7
8
# 在my.cnf里面添加以下内容
[mysqld]
log-bin = master-binlog
innodb_file_per_table = 1
server-id = 1
sync_binlog = 1
innodb_flush_logs_at_trx_commit = 1
sync_master_info = 1

创建有复制权限的用户账号

1
2
mysql> grant replication slave,replication client on *.* to 'repuser'@'%' identified by 'password';
mysql> flush privileges;

4.3.2、从节点配置过程

启动中继日志

为当前节点设置全局唯一的ID号

设置为只读状态(不影响主从复制)

1
2
3
4
5
6
7
8
9
10
11
# 在my.cnf里面添加以下内容
[mysqld]
skip_slave_start = 1
relay-log = relay-log
relay-log = relay-log.index
server-id = 2
innodb_file_per_table = 1
skip_name_resolve = 1
read_only = 1
sync_relay_log = 1
sync_relay_log_info = 1

使用有复制权限的用户账号连接到主服务器,并启动复制线程

1
2
mysql> change master to master_host='master-node',master_user='repuser',master_password='password',master_port=3306,master_log_file='mater-log.003',master_log_pos=1111,master_connect_retry=10;
mysql> start slave ;

查看从状态信息

1
mysql> show slave status\G;

4.3.3、启动semicsync插件

主节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 安装半同步复制master插件
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
mysql> show plugins;
+----------------------------+----------+--------------------+--------------------+---------+
| Name | Status | Type | Library | License |
+----------------------------+----------+--------------------+--------------------+---------+
| rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL |
+----------------------------+----------+--------------------+--------------------+---------+
mysql> > show global variables like '%semi%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+-------------------------------------------+------------+
# 启动半同步复制master节点
mysql> set global variables rpl_semi_sync_master_enable = 1
mysql> show status like '%semi_sync_%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
| Rpl_semi_sync_slave_status | OFF |
+--------------------------------------------+-------+

从节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 停止从节点复制线程
mysql> stop slave;
# 安装半同步复制Slave插件
mysql> install plugin rpl_semi_sync_master soname 'semisync_slave.so';
mysql> > show plugins;
+----------------------------+----------+--------------------+--------------------+---------+
| Name | Status | Type | Library | License |
+----------------------------+----------+--------------------+--------------------+---------+
| rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL |
+----------------------------+----------+--------------------+--------------------+---------+
mysql> > show global variables like '%semi%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+-------------------------------------------+------------+
# 启动半同步复制Slave插件
mysql> set global variables rpl_semi_sync_slave_enabled=1;
mysql> show status like '%semi_sync_%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+--------------------------------------------+-------+
# 开启从节点复制线程
mysql> start slave;

5、复制过滤

5.1、主服务器

1
2
3
4
5
6
[mysqld]
# 数据库记录到binlog
binlog_do_db = db1
binlog_do_db = db2
# 忽略数据库
binlog_ignore_db = db1,db2

5.2、从服务器

1
2
3
4
5
6
7
8
9
[mysqld]
# 复制数据库
replicate_do_db = db1,db2
# 忽略复制数据库
replicate_ignore_db = db1,db2
# 复制表
replicate_do_table = db.table1,db.table2
# 忽略复制表
replicate_ingore_table = db.table1,db.table2

6、监控维护

6.1、相关文件

6.1.1、master.info

保存Slave连接至master时的相关信息,例如账号密码、服务器地址、Position等

6.1.2、relay-log.info

保存当前Slave节点已经复制的当前二进制日志与本地relay-log日志的对应项

6.2、清理日志

6.3、复制监控

1
2
3
4
5
mysql> show master status;
mysql> show binlog events;
mysql> show binary logs;
mysql> show slave status;
mysql> show processlist;

6.4、从服务器是否落后于主服务器

1
2
mysql> show slave status \G;
Seconds_Behind_Master: 0

6.5、确定主从数据是否一致

1
2
3
4
5
6
7
8
9
10
# 安装依赖包
yum install perl-Time-HiRes -y
# 下载二进制包
wget https://www.percona.com/downloads/percona-toolkit/3.0.12/binary/tarball/percona-toolkit-3.0.12_x86_64.tar.gz
# 解压
tar xzf percona-toolkit-3.0.12_x86_64.tar.gz
mv percona-toolkit-3.0.12 /usr/local/
ln -sv /usr/local/percona-toolkit-3.0.12 /usr/local/percona-toolkit
# 运行工具检查
pt-table-checksum

6.6、数据不一致如何处理

重新同步

七、MHA(Master High Availability)

1、介绍

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Mananger可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点中,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他slave重新指向新的master。整个故障转移过程对应用程序完全透明。

在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失,但这这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。

2、MHA组件

Manager节点

  • masterha_check_ssh:MHA依赖的SSH环境检测工具
  • masterha_check_repl:MySQL复制环境检测工具
  • masterha_manager:MHA服务主程序
  • masterha_check_status:MHA运行状态探测工具
  • masterha_master_monitor:MySQL master节点监测工具
  • masterha_master_switch:master节点切换工具
  • masterha_conf_host:添加删除配置的节点
  • masterha_stop:关闭MHA服务

Node节点

  • save_binary_logs:保存复制master的binlog
  • apply_diff_relay_logs:识别差异的中继日志事件并应用到其他slave
  • filter_mysqlbinlog:去除不必要的rollback事件(已弃用)
  • purge_relay_logs:清除中继日志(不阻塞SQL线程)

自定义扩展

  • secondary_check_script:通过多条网络路由检查master可用性
  • master_ip_failover_script:更新Application使用的master IP地址
  • shutdown_script:关闭master节点
  • report_script:发送报告
  • init_conf_load_script:加载初始化配置参数
  • master_ip_online_chage_script:更新master节点IP地址

3、准备MHA环境

3.1、MHA对MySQL复制环境有特殊要求

  • 各节点开启二进制日志和中继日志
  • 从节点需要配置read-only,关闭relay_log_purge

3.2、服务器角色分配

  • manager:MHA Manager
  • db1:master节点
  • db2:slave节点
  • db3:slave节点

3.3、环境准备

各节点启用epel源

各节点/etc/hosts文件

1
2
3
4
5
vi /etc/hosts
10.0.0.10 manager
10.0.0.11 db1
10.0.0.12 db2
10.0.0.13 db3

初始master节点配置

1
2
3
4
5
[mysqld]
# server_id必须唯一
server_id=1
relay-log=relay-log
log-bin=master-bin

初始Slave节点配置

1
2
3
4
5
6
7
[mysqld]
# server_id必须唯一
server_id=2
relay-log=relay-log
log-bin=master-bin
relay_log_purge=0
read_only=1

配置主从复制

db1配置为master节点

db2、db3以db1为master节点,开启slave线程

所有数据库节点创建MHA所需的管理用户

1
mysql> grant all privileges on *.* to 'mhauser'@'%' identified by 'password';

配置manager、db1、db2、db3免密码SSH连接

1
2
3
4
5
6
7
8
9
10
11
12
13
# 在manager节点上配置证书,分发到其他节点
# 下面以root用户为例
ssh-keygen -t rsa
cat /root/.ssh/id_rsa > /root/.ssh/authorized_keys
chmod 0600 /root/.ssh/authorized_keys
for i in db1 db2 db3;
do
scp -p .ssh/id_rcs .ssh/authorized_keys $i:/root/.ssh/
done
for i in manager db1 db2 db3;
do
ssh $i date
done

3.4、安装MHA

3.4.1、node节点安装

1
2
3
4
# 安装依赖包
yum install perl perl-DBD-MySQL -y
wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
yum localinstall mha4mysql-node-0.58-0.el7.centos.noarch.rpm

3.4.2、manager节点安装配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 安装perl相关软件包
yum install perl perl-DBD-MySQL -y
# 下载安装mha4mysql-manager软件包
wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
yum localinstall mha4mysql-manager-0.58-0.el7.centos.noarch.rpm -y
# 编辑MHA配置文件/etc/mha_app1.conf
cat > /etc/mha_app1.conf <<EOF
[server default]
# mysql创建给MHA使用的账号密码
user=root
password=supersecure
# manager工作目录
manager_workdir=/data/masterha/app1
# manager日志路径
manager_log=/data/masterha/app1/manager.log
# MySQL工作目录
remote_workdir=/data/masterha/app1
# ssh使用的用户
ssh_user=root
repl_user=repluser
repl_password=password
ping_interval=1
[server1]
hostname=db1
# ssh_port=22222
candidate_master=1
[server2]
hostname=db2
candidate_master=1
[server3]
hostname=db3
# 禁止节点切换成master节点可以配置no_master=1
EOF

3.4.3、manager节点检测配置和启动

1
2
3
4
5
6
7
8
9
10
# 检查各节点ssh互信通信配置
masterha_check_ssh --conf=/etc/mha_app1.conf
# 检查受管MySQL复制集群配置
masterha_check_repl --conf=/etc/mha_app1.conf
# 启动mha4mysql-manager
masterha_manager --conf=/etc/mha_app1.conf
# 检查mha4mysql-manager状态
masterha_check_status --conf=/etc/mha_app1.conf
# 关闭mha4mysql-manager服务
masterha_stop --conf=/etc/mha_app1.conf

3.4.4、MHA注意点

  • keepalived提供VIP和master切换的对应脚本
  • masterha_manager启动参数
    • –remove_dead_master_conf,当发生主从切换后,老的主库的IP将会从配置文件中移除
    • –ignore_last_failover,MHA切换时会产生app1.failover.complete文件,两次切换时间少于8小时会切换失败,使用该参数能忽略

八、复制的问题和解决

1、数据损坏和丢失

  • Master
    • MHA + 半同步复制
  • Slave
    • 重新复制

2、混合使用存储引擎

  • MyISAM不支持事务
  • InnoDB支持事务

3、server_id不唯一

  • 重新复制

4、复制延迟

  • 需要额外的监控工具辅助

九、Percona XtraDB Cluster

1、介绍

项目地址: http://www.percona.com/doc/percona-xtradb-cluster/intro.html

Percona XtraDB Cluster是MySQL高可用性和可扩展性的解决方案.

Percona XtraDB Cluster提供的特性有:

  • 同步复制,事务要么在所有节点提交或不提交。

  • 多主复制,可以在任意节点进行写操作。

  • 在从服务器上并行应用事件,真正意义上的并行复制。

  • 节点自动配置。

  • 数据一致性,不再是异步复制。

Percona XtraDB Cluster完全兼容MySQL和Percona Server,表现在:

  • 数据的兼容性

  • 应用程序的兼容性:无需更改应用程序

2、特点

  • 当执行一个查询时,在本地节点上执行。因为所有数据都在本地,无需远程访问。
  • 无需集中管理。可以在任何时间点失去任何节点,但是集群将照常工作。
  • 良好的读负载扩展,任意节点都可以查询。
  • 加入新节点,开销大。需要复制完整的数据。
  • 不能有效的解决写缩放问题,所有的写操作都将发生在所有节点上。
  • 有多少个节点就有多少重复的数据。

3、局限性

  • 目前的复制仅仅支持InnoDB存储引擎。任何写入其他引擎的表,包括mysql.*表将不会复制。但是DDL语句会被复制的,因此创建用户将会被复制,但是insert into mysql.user…将不会被复制的。
  • DELETE操作不支持没有主键的表。没有主键的表在不同的节点顺序将不同,如果执行SELECT…LIMIT… 将出现不同的结果集。
  • 在多主环境下LOCK/UNLOCK TABLES不支持。以及锁函数GET_LOCK(), RELEASE_LOCK()..
  • 查询日志不能保存在表中。如果开启查询日志,只能保存到文件中。
  • 允许最大的事务大小由wsrep_max_ws_rows和wsrep_max_ws_size定义。任何大型操作将被拒绝。如大型的LOAD DATA操作。
  • 由于集群是乐观的并发控制,事务commit可能在该阶段中止。如果有两个事务向在集群中不同的节点向同一行写入并提交,失败的节点将中止。对于集群级别的中止,集群返回死锁错误代码(Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK)).
  • XA事务不支持,由于在提交上可能回滚。
  • 整个集群的写入吞吐量是由最弱的节点限制,如果有一个节点变得缓慢,那么整个集群将是缓慢的。为了稳定的高性能要求,所有的节点应使用统一的硬件。
  • 集群节点建议最少3个。2个也可以运行,但是官方不推荐这么做,因为3个节点是为了预防脑裂。
  • 如果DDL语句有问题将破坏集群。建议使用pt-online-schema-change操作DDL。

4、安装galera-cluster

4.1、软件包

官网下载地址

官方文档地址

4.2、准备工作

1
2
3
4
# cat /etc/hosts
10.0.0.11 db1
10.0.0.12 db2
10.0.0.13 db3

节点一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
[root@db1 ~]# mkdir -p /usr/local/pxc
[root@db1 ~]# mkdir -p /data/pxc/mysql3306/{data,tmp,logs}

[root@db1 ~]# vi /etc/my.cnf
[client]
port = 3306
socket = /data/pxc/mysql3306/tmp/mysql.sock
# The MySQL server
[mysqld]
#########Basic##################
explicit_defaults_for_timestamp=true

port = 3306
user = mysql
basedir = /usr/local/pxc
datadir = /data/pxc/mysql3306/data
tmpdir = /data/pxc/mysql3306/tmp
pid-file = /data/pxc/mysql3306/tmp/mysql.pid
socket = /data/pxc/mysql3306/tmp/mysql.sock
#skip-grant-tables

#character set
character_set_server = utf8

open_files_limit = 65535
back_log = 500
#event_scheduler = ON
#lower_case_table_names=1
skip-external-locking
skip_name_resolve = 1
default-storage-engine = InnoDB

#timeout
wait_timeout=1000
interactive_timeout=1000
connect_timeout = 20

server-id = 11 #ip最后一位

#plugin
plugin-load="semisync_master.so;semisync_slave.so"

#########error log#############
log-error = /data/pxc/mysql3306/logs/error.log
log-warnings = 2

#########general log#############
#general_log=1
#general_log_file=/data/pxc/mysql3306/logs/mysql.log

#########slow log#############
slow_query_log = 1
long_query_time=1
slow_query_log_file = /data/pxc/mysql3306/logs/mysql.slow


############# for replication###################
log-bin = /data/pxc/mysql3306/logs/mysql-bin
binlog_format = row
max_binlog_size = 50M
binlog_cache_size = 2M
max_binlog_cache_size = 2M
expire-logs-days = 7
slave-net-timeout=30
log_bin_trust_function_creators = 1
log-slave-updates = 1
skip-slave-start = 1
#super_read_only =1
#GTID
gtid-mode = on
binlog_gtid_simple_recovery=1
enforce_gtid_consistency=1
#relay log
relay-log = /data/pxc/mysql3306/logs/mysql-relay
relay-log-index=/data/pxc/mysql3306/logs/relay-bin.index
max-relay-log-size = 500M
#replication crash safe
sync_master_info = 1
sync_relay_log_info = 1
sync_relay_log = 1
relay_log_recovery = 1
master_info_repository = TABLE
relay_log_info_repository = TABLE
#######per_thread_buffers#####################
max_connections=1100
max_user_connections=1000
max_connect_errors=10000
#myisam_recover
key_buffer_size = 64M
max_allowed_packet = 16M
#table_cache = 3096
table_open_cache = 6144
table_definition_cache = 4096
read_buffer_size = 1M
join_buffer_size = 128K
read_rnd_buffer_size = 1M
#myisam
sort_buffer_size = 128K
myisam_max_sort_file_size = 1G
myisam_repair_threads = 1
myisam_sort_buffer_size = 32M
tmp_table_size = 32M
max_heap_table_size = 64M
query_cache_type=0
query_cache_size = 0
bulk_insert_buffer_size = 32M
thread_cache_size = 64
#thread_concurrency = 32
thread_stack = 192K
###############InnoDB###########################
innodb_data_home_dir = /data/pxc/mysql3306/data
innodb_log_group_home_dir = /data/pxc/mysql3306/logs
innodb_data_file_path = ibdata1:10M:autoextend
innodb_buffer_pool_size = 512M #根据内存大小设置
innodb_buffer_pool_instances = 8
#innodb_additional_mem_pool_size = 16M
innodb_log_file_size = 50M
innodb_log_buffer_size = 16M
innodb_log_files_in_group = 3
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
innodb_lock_wait_timeout = 10
innodb_sync_spin_loops = 40
innodb_max_dirty_pages_pct = 80
innodb_support_xa = 1
innodb_thread_concurrency = 0
innodb_thread_sleep_delay = 500
innodb_concurrency_tickets = 1000
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_read_io_threads = 16
innodb_write_io_threads = 16
innodb_io_capacity = 800
innodb_flush_neighbors = 1
innodb_file_format = Barracuda
innodb_purge_threads=4
innodb_purge_batch_size = 32
innodb_old_blocks_pct=75
innodb_change_buffering=all
innodb_stats_on_metadata=OFF
innodb_print_all_deadlocks = 1
performance_schema=0
transaction_isolation = READ-COMMITTED
############# PXC #####################
innodb_autoinc_lock_mode=2
wsrep_cluster_name=pxc-dongzheng
wsrep_provider=/usr/local/pxc/lib/libgalera_smm.so
wsrep_cluster_address=gcomm://10.0.0.11,10.0.0.12,10.0.13
wsrep_node_address=10.0.0.11 # 本机IP地址
wsrep_slave_threads=2
wsrep_sst_auth=sst:sky
wsrep_sst_method=xtrabackup-v2
wsrep_provider_options="debug=1"
[mysqldump]
quick
max_allowed_packet = 128M
[mysql]
no-auto-rehash
max_allowed_packet = 128M
prompt = '(product)\u@\h:\p [\d]> '
default_character_set = utf8
[myisamchk]
key_buffer_size = 64M
sort_buffer_size = 512k
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
[mysqld_safe]
#malloc-lib= /usr/local/mysql/lib/mysql/libjemalloc.so

节点二、节点三修改my.cnf里面的对应值就行

  • wsrep_node_address =

  • server-id =

4.3、启动集群

先初始化节点一,将节点一加入集群

1
2
3
# 启动集群
mysqld --defaults-file=/etc/my.cnf --initialize-insecure
mysqld --defaults-file=/etc/my.cnf --wsrep-new-cluster &
1
2
# 创建账号
mysql> GRANT PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'sst'@'localhost'IDENTIFIED BY 'sky';FLUSH PRIVILEGES;

节点二、节点三加入集群

1
mysqld --defaults-file=/etc/my.cnf &