sysbench 测试MySQL磁盘IOPS

sysbench 测试MySQL磁盘IOPS
1. 安装

https://github.com/akopytov/sysbench.git # 通过git clone得到源码

2. 上传到MySQL服务器并解压

[root@localhost soft]# unzip sysbench-master.zip
[root@localhost soft]# mv sysbench-master sysbench

[root@localhost sysbench]# ./autogen.sh
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal -I m4
autoreconf: configure.ac: tracing
autoreconf: running: libtoolize --copy
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, `config'.
libtoolize: copying file `config/ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
autoreconf: running: /usr/bin/autoconf
autoreconf: running: /usr/bin/autoheader
autoreconf: running: automake --add-missing --copy --no-force
configure.ac:59: installing 'config/ar-lib'
configure.ac:45: installing 'config/compile'
configure.ac:27: installing 'config/config.guess'
configure.ac:27: installing 'config/config.sub'
configure.ac:32: installing 'config/install-sh'
configure.ac:32: installing 'config/missing'
src/Makefile.am: installing 'config/depcomp'
parallel-tests: installing 'config/test-driver'
autoreconf: Leaving directory `.'

2.1 关联mysql的头文件和库

[root@localhost sysbench]# ./configure  --with-mysql-includes=/mysqlsoft/mysql/include/  --with-mysql-libs=/mysqlsoft/mysql/lib/
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking minix/config.h usability... no
checking minix/config.h presence... no
checking for minix/config.h... no
checking whether it is safe to define __EXTENSIONS__... yes
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking for gcc option to accept ISO C99... -std=gnu99
checking how to run the C preprocessor... gcc -E
checking whether gcc -std=gnu99 and cc understand -c and -o together... yes
checking for a sed that does not truncate output... /usr/bin/sed
checking for C compiler vendor... gnu
checking for gcc architecture flag...
checking for x86 cpuid 0 output... d:756e6547:6c65746e:49656e69
checking for x86 cpuid 1 output... 306e7:2040800:9e982203:1fabfbff
checking whether C compiler accepts -march=ivybridge... no
checking whether C compiler accepts -march=core-avx-i... yes
checking for gcc architecture flag... -march=core-avx-i
checking for ar... ar
checking the archiver (ar) interface... ar
checking how to print strings... printf
checking for a sed that does not truncate output... (cached) /usr/bin/sed
checking for fgrep... /usr/bin/grep -F
checking for ld used by gcc -std=gnu99... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking how to convert x86_64-unknown-linux-gnu file names to x86_64-unknown-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-unknown-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from gcc -std=gnu99 object... ok
checking for sysroot... no
checking for mt... mt
checking if mt is a manifest tool... no
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc -std=gnu99 supports -fno-rtti -fno-exceptions... no
checking for gcc -std=gnu99 option to produce PIC... -fPIC -DPIC
checking if gcc -std=gnu99 PIC flag -fPIC -DPIC works... yes
checking if gcc -std=gnu99 static flag -static works... no
checking if gcc -std=gnu99 supports -c -o file.o... yes
checking if gcc -std=gnu99 supports -c -o file.o... (cached) yes
checking whether the gcc -std=gnu99 linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking for pkg-config... yes
checking for C compiler vendor... (cached) gnu
checking whether to compile with MySQL support... yes
checking whether to compile with PostgreSQL support... no
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking whether to build with system or bundled LuaJIT... bundled
checking whether to build with system or bundled Concurrency Kit... bundled
checking whether SHM_HUGETLB is declared... yes
checking whether O_SYNC is declared... yes
checking for the pthreads library -lpthreads... no
checking whether pthreads work without any flags... no
checking whether pthreads work with -Kthread... no
checking whether pthreads work with -kthread... no
checking for the pthreads library -llthread... no
checking whether pthreads work with -pthread... yes
checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE
checking if more special flags are required for pthreads... no
checking for sqrt in -lm... yes
checking MySQL includes... (cached) /mysqlsoft/mysql/include/
checking MySQL libraries... (cached) /mysqlsoft/mysql/lib/
checking for library containing mysql_real_connect... -lmysqlclient
checking if mysql.h defines MYSQL_OPT_SSL_MODE... yes
checking libaio.h usability... no
checking libaio.h presence... no
checking for libaio.h... no
checking for ANSI C header files... (cached) yes
checking errno.h usability... yes
checking errno.h presence... yes
checking for errno.h... yes
checking fcntl.h usability... yes
checking fcntl.h presence... yes
checking for fcntl.h... yes
checking math.h usability... yes
checking math.h presence... yes
checking for math.h... yes
checking pthread.h usability... yes
checking pthread.h presence... yes
checking for pthread.h... yes
checking sched.h usability... yes
checking sched.h presence... yes
checking for sched.h... yes
checking signal.h usability... yes
checking signal.h presence... yes
checking for signal.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking sys/aio.h usability... no
checking sys/aio.h presence... no
checking for sys/aio.h... no
checking sys/ipc.h usability... yes
checking sys/ipc.h presence... yes
checking for sys/ipc.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking sys/mman.h usability... yes
checking sys/mman.h presence... yes
checking for sys/mman.h... yes
checking sys/shm.h usability... yes
checking sys/shm.h presence... yes
checking for sys/shm.h... yes
checking thread.h usability... no
checking thread.h presence... no
checking for thread.h... no
checking for unistd.h... (cached) yes
checking limits.h usability... yes
checking limits.h presence... yes
checking for limits.h... yes
checking libgen.h usability... yes
checking libgen.h presence... yes
checking for libgen.h... yes
checking for off_t... yes
checking whether time.h and sys/time.h may both be included... yes
checking for thread local storage (TLS) class... __thread
checking for __attribute__((format))... yes
checking for __attribute__((unused))... yes
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
checking size of size_t... 8
checking size of bool... 1
checking for stdlib.h... (cached) yes
checking for unistd.h... (cached) yes
checking for sys/param.h... yes
checking for getpagesize... yes
checking for working mmap... yes
checking whether strerror_r is declared... yes
checking for strerror_r... yes
checking whether strerror_r returns char *... yes
checking for library containing clock_gettime... none required
checking for alarm... yes
checking for clock_gettime... yes
checking for directio... no
checking for fdatasync... yes
checking for gettimeofday... yes
checking for isatty... yes
checking for memalign... yes
checking for memset... yes
checking for posix_memalign... yes
checking for pthread_cancel... yes
checking for pthread_yield... yes
checking for setvbuf... yes
checking for sqrt... yes
checking for strdup... yes
checking for thr_setconcurrency... no
checking for valloc... yes
checking for pthread_once... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating third_party/luajit/Makefile
config.status: creating third_party/concurrency_kit/Makefile
config.status: creating src/Makefile
config.status: creating src/drivers/Makefile
config.status: creating src/drivers/mysql/Makefile
config.status: creating src/drivers/pgsql/Makefile
config.status: creating src/tests/Makefile
config.status: creating src/tests/cpu/Makefile
config.status: creating src/tests/fileio/Makefile
config.status: creating src/tests/memory/Makefile
config.status: creating src/tests/threads/Makefile
config.status: creating src/tests/mutex/Makefile
config.status: creating src/lua/Makefile
config.status: creating src/lua/internal/Makefile
config.status: creating tests/Makefile
config.status: creating tests/include/config.sh
config.status: creating snap/snapcraft.yaml
config.status: creating config/config.h
config.status: executing depfiles commands
config.status: executing libtool commands
===============================================================================
sysbench version   : 1.1.0
CC                 : gcc -std=gnu99
CFLAGS             : -O3 -funroll-loops -ggdb3  -march=core-avx-i -Wall -Wextra -Wpointer-arith -Wbad-function-cast -Wstrict-prototypes -Wnested-externs -Wno-format-zero-length -Wundef -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wcast-align -Wvla   -pthread
CPPFLAGS           : -D_GNU_SOURCE   -I$(top_srcdir)/src -I$(abs_top_builddir)/third_party/luajit/inc -I$(abs_top_builddir)/third_party/concurrency_kit/include
LDFLAGS            : -L/usr/local/lib
LIBS               : -lm

prefix             : /usr/local
bindir             : ${prefix}/bin
libexecdir         : ${prefix}/libexec
mandir             : ${prefix}/share/man
datadir            : ${prefix}/share

MySQL support      : yes
PostgreSQL support : no

LuaJIT             : bundled
LUAJIT_CFLAGS      : -I$(abs_top_builddir)/third_party/luajit/inc
LUAJIT_LIBS        : $(abs_top_builddir)/third_party/luajit/lib/libluajit-5.1.a -ldl
LUAJIT_LDFLAGS     : -rdynamic

Concurrency Kit    : bundled
CK_CFLAGS          : -I$(abs_top_builddir)/third_party/concurrency_kit/include
CK_LIBS            : $(abs_top_builddir)/third_party/concurrency_kit/lib/libck.a
configure flags    :
===============================================================================

2.2 编译源码
[root@localhost sysbench]# make -j 4

2.3 安装(默认安装到 /usr/local/bin , 如果有自定义目录,configure增加参数 –prefix=自定义目录)
[root@localhost sysbench]# make install

添加LD_LIBRARY_PATH

[root@localhost ~]# echo "export LD_LIBRARY_PATH=/mysqlsoft/mysql/lib/:$LD_LIBRARY_PATH" >> ~/.bashrc

[root@localhost ~]# source ~/.bashrc
[root@localhost ~]# sysbench –version
sysbench 1.1.0

3. 测试
生成测试文件

[root@localhost ~]# sysbench  fileio   help
sysbench 1.1.0 (using bundled LuaJIT 2.1.0-beta3)

fileio options:
  --file-num=N                  number of files to create [128]
  --file-block-size=N           block size to use in all IO operations [16384]
  --file-total-size=SIZE        total size of files to create [2G]
  --file-test-mode=STRING       test mode {seqwr, seqrewr, seqrd, rndrd, rndwr, rndrw}
  --file-io-mode=STRING         file operations mode {sync,async,mmap} [sync]
  --file-extra-flags=[LIST,...] list of additional flags to use to open files {sync,dsync,direct} []
  --file-fsync-freq=N           do fsync() after this number of requests (0 - don't use fsync()) [100]
  --file-fsync-all[=on|off]     do fsync() after each write operation [off]
  --file-fsync-end[=on|off]     do fsync() at the end of test [on]
  --file-fsync-mode=STRING      which method to use for synchronization {fsync, fdatasync} [fsync]
  --file-merged-requests=N      merge at most this number of IO requests if possible (0 - don't merge) [0]
  --file-rw-ratio=N             reads/writes ratio for combined test [1.5]

其他说明

  # --file-num=N                  创建文件数
  # --file-block-size=N           block size大小
  # --file-total-size=SIZE        文件数的大小总和
  # --file-test-mode=STRING       测试模式 {seqwr, seqrewr, seqrd, rndrd, rndwr, rndrw} (顺序写,顺序读写,顺序读,随机读,随机写,随机读写)
  # --file-io-mode=STRING         文件操作方式 {sync,async,mmap}
  # --file-extra-flags=STRING     打开文件的额外标志 {sync,dsync,direct} []
  # --file-fsync-freq=N           多少请求后执行fsync。默认是0,不执行
  # --file-fsync-all=[on|off]     是否每次操作后都执行fsync
  # --file-fsync-end=[on|off]     测完成后执行fsync,默认是on
  # --file-fsync-mode=STRING      同步的方法 {fsync, fdatasync}默认是 [fsync]
  # --file-merged-requests=N      最多多少IO请求被合并,默认为0,不合并
  # --file-rw-ratio=N             读写比例默认是 [1.5],即 3:2
[root@localhost ~]# sysbench  fileio --file-num=4 --file-block-size=8K --file-total-size=1G --file-test-mode=rndrd --file-extra-flags=direct prepare
sysbench 1.1.0 (using bundled LuaJIT 2.1.0-beta3)

4 files, 262144Kb each, 1024Mb total
Creating files for the test...
Extra file open flags: directio
Creating file test_file.0
Creating file test_file.1
Creating file test_file.2
Creating file test_file.3
1073741824 bytes written in 29.00 seconds (35.30 MiB/sec).

开始测试(–time=30简单测试,测试30秒 –report-interval=3 # 每3秒产生报告)

[root@localhost ~]# sysbench  fileio  --file-num=4  --file-block-size=8K  --file-total-size=1G  --file-test-mode=rndrd  --file-extra-flags=direct  --threads=4 --time=30 --report-interval=3  run
sysbench 1.1.0 (using bundled LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 4
Report intermediate results every 3 second(s)
Initializing random number generator from current time


Extra file open flags: directio
4 files, 256MiB each
1GiB total file size
Block size 8KiB
Number of IO requests: 0
Read/Write ratio for combined random IO test: 1.50
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random read test
Initializing worker threads...

Threads started!

[ 3s ] reads: 4.48 MiB/s writes: 0.00 MiB/s fsyncs: 0.00/s latency (ms,95%): 15.268
[ 6s ] reads: 4.39 MiB/s writes: 0.00 MiB/s fsyncs: 0.00/s latency (ms,95%): 15.828
[ 9s ] reads: 4.61 MiB/s writes: 0.00 MiB/s fsyncs: 0.00/s latency (ms,95%): 14.995
[ 12s ] reads: 4.73 MiB/s writes: 0.00 MiB/s fsyncs: 0.00/s latency (ms,95%): 13.953
[ 15s ] reads: 4.77 MiB/s writes: 0.00 MiB/s fsyncs: 0.00/s latency (ms,95%): 13.953
[ 18s ] reads: 4.81 MiB/s writes: 0.00 MiB/s fsyncs: 0.00/s latency (ms,95%): 14.207
[ 21s ] reads: 4.82 MiB/s writes: 0.00 MiB/s fsyncs: 0.00/s latency (ms,95%): 14.728
[ 24s ] reads: 4.84 MiB/s writes: 0.00 MiB/s fsyncs: 0.00/s latency (ms,95%): 14.995
[ 27s ] reads: 5.09 MiB/s writes: 0.00 MiB/s fsyncs: 0.00/s latency (ms,95%): 13.953
[ 30s ] reads: 5.16 MiB/s writes: 0.00 MiB/s fsyncs: 0.00/s latency (ms,95%): 14.207

Throughput:
         read:  IOPS=610.59 4.77 MiB/s (5.00 MB/s) #4.77*1024/8;
         write: IOPS=0.00 0.00 MiB/s (0.00 MB/s)
         fsync: IOPS=0.00

Latency (ms):
         min:                                  0.18
         avg:                                  6.54
         max:                                 45.86
         95th percentile:                     14.46
         sum:                             119902.59

MySQL 5.7配置SSL连接

MySQL 5.7配置SSL连接

如果想服务能够部署自动支持安全连接,使用mysql_ssl_rsa_setup工具来创建缺省SSL与RSA文件

[root@cs2 bin]# ./mysql_ssl_rsa_setup --datadir=/mysqldata/mysql
Generating a 2048 bit RSA private key
......................................................................+++
..............................................................+++
writing new private key to 'ca-key.pem'
-----
Generating a 2048 bit RSA private key
.............+++
..............+++
writing new private key to 'server-key.pem'
-----
Generating a 2048 bit RSA private key
.....................................+++
................................................+++
writing new private key to 'client-key.pem'
-----





启动mysql

[root@cs2 ~]# service mysqld start
Starting MySQL.. SUCCESS!

测试远程登录

-bash-4.2$ mysql -h 10.11.13.19 -P 3306 -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.22 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT DISTINCT CONCAT('User: [', user, '''@''', host, '];') AS USER_HOST FROM user;
+------------------------------------+
| USER_HOST                          |
+------------------------------------+
| User: [root'@'%];                  |
| User: [mysql.session'@'localhost]; |
| User: [mysql.sys'@'localhost];     |
+------------------------------------+
3 rows in set (0.05 sec)

通过ssl登录mysql服务器

[mysql@localhost ~]$ mysql -h 10.11.13.19 -P 3306 -u root -pabcd123 --ssl-cert=client-cert.pem --ssl-key=client-key.pem
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.7.26, for Linux (x86_64) using  EditLine wrapper

Connection id:          7
Current database:
Current user:           root@10.11.13.19
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         5.7.26-log Source distribution
Protocol version:       10
Connection:             10.11.13.19 via TCP/IP
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    gb2312
Conn.  characterset:    gb2312
TCP port:               3306
Uptime:                 14 min 11 sec

Threads: 2  Questions: 13  Slow queries: 0  Opens: 108  Flush tables: 1  Open tables: 101  Queries per second avg: 0.015
--------------

mysql> show variables like 'have_ssl';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_ssl      | DISABLED |
+---------------+----------+
1 row in set (0.01 sec)

mysql> show variables like 'require_secure_transport';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| require_secure_transport | OFF   |
+--------------------------+-------+
1 row in set (0.00 sec)

mysql> show variables like '%ssl%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| have_openssl  | DISABLED        |
| have_ssl      | DISABLED        |
| ssl_ca        | ca.pem          |
| ssl_capath    |                 |
| ssl_cert      | server-cert.pem |
| ssl_cipher    |                 |
| ssl_crl       |                 |
| ssl_crlpath   |                 |
| ssl_key       | server-key.pem  |
+---------------+-----------------+

从上面的查询结果可以看到SSL: Not in use,have_ssl和have_openssl为DISABLED,这说明实际上是没有启用ssl。

这是因为通过执行mysql_ssl_rsa_setup命令产生的pem文件的权限为root用户而不是mysql用户造成的,将这些pem文件的权限修改为mysql用户与组 权限不要太大,只用户权限为rw,组与其它用户需要r权限

[root@localhost mysql]# ls -lrt
30172
-rw-r-----. 1 mysql mysql 104857600 321 16:25 ib_logfile1
-rw-r-----. 1 mysql mysql 104857600 321 16:25 ib_logfile2
drwxr-x---. 2 mysql mysql        48 321 16:25 undo
-rw-r-----. 1 mysql mysql        56 321 16:25 auto.cnf
drwxr-x---. 2 mysql mysql      8192 321 16:25 performance_schema
drwxr-x---. 2 mysql mysql      4096 321 16:25 mysql
drwxr-x---. 2 mysql mysql      8192 321 16:25 sys
-rw-r-----. 1 mysql mysql       177 321 16:25 binlog.000001
-rw-r--r--. 1 mysql mysql      1679 321 16:26 ca-key.pem
-rw-r--r--. 1 mysql mysql      1107 321 16:26 ca.pem
-rw-r--r--. 1 root  root       1679 321 16:26 server-key.pem
-rw-r--r--. 1 root  root       1107 321 16:26 server-cert.pem
-rw-r--r--. 1 root  root      1675 321 16:26 client-key.pem
-rw-r--r--. 1 root  root      1107 321 16:26 client-cert.pem
-rw-r--r--. 1 root  root      1675 321 16:26 private_key.pem
-rw-r--r--. 1 root  root       451 321 16:26 public_key.pem
-rw-r-----. 1 mysql mysql    114688 524 17:00 ts2.ibd
-rw-r-----. 1 mysql mysql     98304 524 17:01 ts1.ibd
drwxr-x---. 2 mysql mysql        32 524 17:11 test
-rw-r-----. 1 mysql mysql      9352 621 10:46 binlog.000002
-rw-r-----. 1 mysql mysql       177 621 10:46 binlog.000003
-rw-r-----. 1 mysql mysql       154 9 9 19:55 binlog.000004
-rw-r-----. 1 mysql mysql       177 9 9 20:23 binlog.000005
-rw-r-----. 1 mysql mysql       177 9 9 20:38 binlog.000006
-rw-r-----. 1 mysql mysql       177 9 9 20:44 binlog.000007
-rw-r-----. 1 mysql mysql       122 9 9 20:44 ib_buffer_pool
-rw-r-----. 1 mysql mysql       248 9 9 20:44 binlog.index
-rw-r-----. 1 mysql mysql       154 9 9 20:44 binlog.000008
-rw-r-----. 1 mysql mysql         6 9 9 20:44 mysqld.pid
-rw-r-----. 1 mysql mysql  12582912 9 9 20:44 ibtmp1
-rw-r-----. 1 mysql mysql  10485760 9 9 20:44 ibdata1
-rw-r-----. 1 mysql mysql 104857600 9 9 20:44 ib_logfile0
-rw-r-----. 1 mysql mysql    107011 9 9 20:54 mysql.err

[root@localhost mysql]# chown -R mysql:mysql *.pem
[root@localhost mysql]# ls -lrt
30172
-rw-r-----. 1 mysql mysql 104857600 321 16:25 ib_logfile1
-rw-r-----. 1 mysql mysql 104857600 321 16:25 ib_logfile2
drwxr-x---. 2 mysql mysql        48 321 16:25 undo
-rw-r-----. 1 mysql mysql        56 321 16:25 auto.cnf
drwxr-x---. 2 mysql mysql      8192 321 16:25 performance_schema
drwxr-x---. 2 mysql mysql      4096 321 16:25 mysql
drwxr-x---. 2 mysql mysql      8192 321 16:25 sys
-rw-r-----. 1 mysql mysql       177 321 16:25 binlog.000001
-rw-r--r--. 1 mysql mysql      1679 321 16:26 ca-key.pem
-rw-r--r--. 1 mysql mysql      1107 321 16:26 ca.pem
-rw-r--r--. 1 mysql mysql      1679 321 16:26 server-key.pem
-rw-r--r--. 1 mysql mysql      1107 321 16:26 server-cert.pem
-rw-r--r--. 1 mysql mysql      1675 321 16:26 client-key.pem
-rw-r--r--. 1 mysql mysql      1107 321 16:26 client-cert.pem
-rw-r--r--. 1 mysql mysql      1675 321 16:26 private_key.pem
-rw-r--r--. 1 mysql mysql       451 321 16:26 public_key.pem
-rw-r-----. 1 mysql mysql    114688 524 17:00 ts2.ibd
-rw-r-----. 1 mysql mysql     98304 524 17:01 ts1.ibd
drwxr-x---. 2 mysql mysql        32 524 17:11 test
-rw-r-----. 1 mysql mysql      9352 621 10:46 binlog.000002
-rw-r-----. 1 mysql mysql       177 621 10:46 binlog.000003
-rw-r-----. 1 mysql mysql       154 9 9 19:55 binlog.000004
-rw-r-----. 1 mysql mysql       177 9 9 20:23 binlog.000005
-rw-r-----. 1 mysql mysql       177 9 9 20:38 binlog.000006
-rw-r-----. 1 mysql mysql       177 9 9 20:44 binlog.000007
-rw-r-----. 1 mysql mysql       122 9 9 20:44 ib_buffer_pool
-rw-r-----. 1 mysql mysql       248 9 9 20:44 binlog.index
-rw-r-----. 1 mysql mysql       154 9 9 20:44 binlog.000008
-rw-r-----. 1 mysql mysql         6 9 9 20:44 mysqld.pid
-rw-r-----. 1 mysql mysql  12582912 9 9 20:44 ibtmp1
-rw-r-----. 1 mysql mysql  10485760 9 9 20:44 ibdata1
-rw-r-----. 1 mysql mysql 104857600 9 9 20:44 ib_logfile0
-rw-r-----. 1 mysql mysql    107011 9 9 20:54 mysql.err

pem文件权限太多可能会出现如下错误

[mysql@localhost mysql]$ mysql -h 10.11.13.19 -P 3306 -u root -pabcd123 --ssl-cert=/mysqldata/mysql/client-cert.pem --ssl-key=/mysqldata/mysql/client-key.pem
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2026 (HY000): SSL connection error: SSL_CTX_set_default_verify_paths failed


[root@localhost mysql]# service mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL.. SUCCESS!

[mysql@localhost mysql]$ mysql -h 10.11.13.19 -P 3306 -u root -pabcd123 --ssl-cert=/mysqldata/mysql/client-cert.pem --ssl-key=/mysqldata/mysql/client-key.pem
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.7.26, for Linux (x86_64) using  EditLine wrapper

Connection id:          4
Current database:
Current user:           root@10.11.13.19
SSL:                    Cipher in use is DHE-RSA-AES256-SHA
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         5.7.26-log Source distribution
Protocol version:       10
Connection:             10.11.13.19 via TCP/IP
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    gb2312
Conn.  characterset:    gb2312
TCP port:               3306
Uptime:                 59 sec

Threads: 2  Questions: 11  Slow queries: 0  Opens: 108  Flush tables: 1  Open tables: 101  Queries per second avg: 0.186
--------------

创建用户限制用户必须用ssl登录

mysql> create user 'jy'@'%' identified by "123";
Query OK, 0 rows affected (0.02 sec)

mysql> grant all on *.* to 'jy'@'%' require ssl;
Query OK, 0 rows affected, 1 warning (0.02 sec)

虽然要求用ssl但是还是可以使用密码登录,是因为mysql.user表中的ssl_type=ANY

[mysql@localhost ~]$  mysql -h 10.11.13.19 -P 3306 -u jy -p123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.7.26, for Linux (x86_64) using  EditLine wrapper

Connection id:          7
Current database:
Current user:           jy@10.11.13.19
SSL:                    Cipher in use is DHE-RSA-AES256-SHA
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         5.7.26-log Source distribution
Protocol version:       10
Connection:             10.11.13.19 via TCP/IP
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    gb2312
Conn.  characterset:    gb2312
TCP port:               3306
Uptime:                 50 min 18 sec

Threads: 2  Questions: 69  Slow queries: 0  Opens: 139  Flush tables: 1  Open tables: 132  Queries per second avg: 0.022
--------------

mysql> select * from user where user='jy'\G
ERROR 1046 (3D000): No database selected
mysql> select * from mysql.user where user='root'\G
*************************** 1. row ***************************
                  Host: %
                  User: jy
           Select_priv: Y
           Insert_priv: Y
           Update_priv: Y
           Delete_priv: Y
           Create_priv: Y
             Drop_priv: Y
           Reload_priv: Y
         Shutdown_priv: Y
          Process_priv: Y
             File_priv: Y
            Grant_priv: Y
       References_priv: Y
            Index_priv: Y
            Alter_priv: Y
          Show_db_priv: Y
            Super_priv: Y
 Create_tmp_table_priv: Y
      Lock_tables_priv: Y
          Execute_priv: Y
       Repl_slave_priv: Y
      Repl_client_priv: Y
      Create_view_priv: Y
        Show_view_priv: Y
   Create_routine_priv: Y
    Alter_routine_priv: Y
      Create_user_priv: Y
            Event_priv: Y
          Trigger_priv: Y
Create_tablespace_priv: Y
              ssl_type: ANY
            ssl_cipher:
           x509_issuer:
          x509_subject:
         max_questions: 0
           max_updates: 0
       max_connections: 0
  max_user_connections: 0
                plugin: mysql_native_password
 authentication_string: *1AA476D99C1600C9D984E248FBF2FDE3A0BB256E
      password_expired: N
 password_last_changed: 2022-03-21 16:27:48
     password_lifetime: NULL
        account_locked: N
1 row in set (0.00 sec)

修改用户jy的ssl类型为x509

mysql> alter user 'jy'@'%' require x509
    -> ;
Query OK, 0 rows affected (0.01 sec)

在不指定ssl密钥时就不能登录了

[mysql@localhost ~]$ mysql -h 10.11.13.19 -P 3306 -u jy -p123
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'jy'@'10.11.13.19' (using password: YES)
[mysql@localhost ~]$  mysql -h 10.11.13.19 -P 3306 -u jy -p123 --ssl
mysql: [Warning] Using a password on the command line interface can be insecure.
WARNING: --ssl is deprecated and will be removed in a future version. Use --ssl-mode instead.
ERROR 1045 (28000): Access denied for user 'jy'@'10.11.13.19' (using password: YES)

指定ssl密钥进行登录

[mysql@localhost ~]$  mysql -h 10.11.13.19 -P 3306 -u jy -p123 --ssl-cert=/mysqldata/mysql/client-cert.pem --ssl-key=/mysqldata/mysql/client-key.pem
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit

如果指定ssl密钥进行登录时不指定密钥完整路径时会出现如下错误

[mysql@localhost ~]$  mysql -h 10.11.13.19 -P 3306 -u jy -p123 --ssl-cert=client-cert.pem --ssl-key=client-key.pem
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql: [ERROR] SSL error: Unable to get certificate from 'client-cert.pem'
ERROR 2026 (HY000): SSL connection error: Unable to get certificate

MySQL 拷贝一个InnoDB分区表到另一个实例

拷贝一个InnoDB分区表到另一个实例
这个过程演示了如何将一个InnoDB分区表从一个正在运行的MySQL服务器实例复制到另一个正在运行的实例。同样的过程,只要稍微做些调整,就可以在同一个实例上对InnoDB分区表执行完全恢复。

1.在源实例上,如果不存在分区表,则创建分区表。在下面的例子中,创建了一个包含三个分区(p0, p1, p2)的表

mysql> use test;
Database changed
mysql> create table t1(i int) engine=innodb partition by key(i) partitions 3;
Query OK, 0 rows affected (0.38 sec)

mysql> insert into t1 values(1),(2),(3),(4),(5),(6),(7),(8),(9);
Query OK, 9 rows affected (0.03 sec)
Records: 9  Duplicates: 0  Warnings: 0
mysql> select * from t1;
+------+
| i    |
+------+
|    4 |
|    5 |
|    1 |
|    6 |
|    7 |
|    2 |
|    3 |
|    8 |
|    9 |
+------+
9 rows in set (0.00 sec)

在/mysqldata/mysql/test目录中,对于三个分区都有一个单独的表空间(.ibd)文件:

[root@localhost ~]# cd /mysqldata/mysql/test
[root@localhost test]# ls -lrt
总用量 304
-rw-r-----. 1 mysql mysql    67 3月  15 16:53 db.opt
-rw-r-----. 1 mysql mysql  8554 3月  16 15:43 t1.frm
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p1.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p2.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p0.ibd

2.在目标实例上,创建相同的分区表:

mysql> use test;
Database changed
mysql> create table t1(i int) engine=innodb partition by key(i) partitions 3;
Query OK, 0 rows affected (0.20 sec)

在/mysqldata/mysql/test目录中,对于三个分区都有一个单独的表空间(.ibd)文件:

[root@localhost ~]# cd /mysqldata/mysql/test
[root@localhost test]# ls -lrt
总用量 304
-rw-r-----. 1 mysql mysql    67 3月  15 16:55 db.opt
-rw-r-----. 1 mysql mysql  8554 3月  16 15:45 t1.frm
-rw-r-----. 1 mysql mysql 98304 3月  16 15:45 t1#P#p0.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:45 t1#P#p1.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:45 t1#P#p2.ibd

3.在目标实例上,丢弃分区表的表空间。(在将表空间导入目标实例之前,必须丢弃附加到接收表的表空间。)

mysql> alter table t1 discard tablespace;
Query OK, 0 rows affected (0.09 sec)

组成分区表表空间的三个.ibd文件从/mysqldata/mysql/tes目录中被丢弃,留下以下文件

[root@localhost ~]# cd /mysqldata/mysql/test
[root@localhost test]# ls -lrt
总用量 16
-rw-r-----. 1 mysql mysql   67 3月  15 16:55 db.opt
-rw-r-----. 1 mysql mysql 8554 3月  16 15:45 t1.frm

4.在源实例上,运行FLUSH TABLES… FOR EXPORT用于暂停分区表并创建.cfg元数据文件

mysql> flush tables t1 for export;
Query OK, 0 rows affected (0.01 sec)

在源实例的/mysqldata/mysql/test目录中创建元数据(.cfg)文件,每个表空间(.ibd)文件对应一个元数据文件

[root@localhost ~]# cd /mysqldata/mysql/test
[root@localhost test]# ls -lrt
总用量 316
-rw-r-----. 1 mysql mysql    67 3月  15 16:53 db.opt
-rw-r-----. 1 mysql mysql  8554 3月  16 15:43 t1.frm
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p1.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p2.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p0.ibd
-rw-r-----. 1 mysql mysql   375 3月  16 16:00 t1#P#p1.cfg
-rw-r-----. 1 mysql mysql   375 3月  16 16:00 t1#P#p0.cfg
-rw-r-----. 1 mysql mysql   375 3月  16 16:00 t1#P#p2.cfg

FLUSH TABLES……FOR EXPORT语句确保对指定表的更改已刷新到磁盘,以便在实例运行时可以进行二进制表拷贝。当运行FLUSH TABLES … FOR EXPORT时,InnoDB会在数据库目录中为表的表空间文件生成一个.cfg元数据文件。.cfg文件中包含导入表空间文件时验证模式的元数据。FLUSH TABLES … FOR EXPORT只能在表上运行,而不能在单独的表分区上运行。

5.将.ibd和.cfg文件从源实例数据库目录复制到目标实例数据库目录。例如

[root@localhost test]# scp t1*.{ibd,cfg} mysql@192.168.1.243:/mysqldata/mysql/test/
mysql@192.168.1.243's password:
t1#P#p0.ibd                                                                                                                                                                                              100%   96KB  96.0KB/s   00:00
t1#P#p1.ibd                                                                                                                                                                                              100%   96KB  96.0KB/s   00:00
t1#P#p2.ibd                                                                                                                                                                                              100%   96KB  96.0KB/s   00:00
t1#P#p0.cfg                                                                                                                                                                                              100%  375     0.4KB/s   00:00
t1#P#p1.cfg                                                                                                                                                                                              100%  375     0.4KB/s   00:00
t1#P#p2.cfg                                                                                                                                                                                              100%  375     0.4KB/s   00:00
[root@localhost test]#

[root@localhost test]# ls -lrt
总用量 316
-rw-r-----. 1 mysql mysql    67 3月  15 16:55 db.opt
-rw-r-----. 1 mysql mysql  8554 3月  16 15:45 t1.frm
-rw-r-----. 1 mysql mysql 98304 3月  16 16:06 t1#P#p0.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 16:06 t1#P#p1.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 16:06 t1#P#p2.ibd
-rw-r-----. 1 mysql mysql   375 3月  16 16:06 t1#P#p0.cfg
-rw-r-----. 1 mysql mysql   375 3月  16 16:06 t1#P#p1.cfg
-rw-r-----. 1 mysql mysql   375 3月  16 16:06 t1#P#p2.cfg

6.在源实例上,使用unlock tables语句来释放由flush tables … for export所获取的锁:

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

在源实例上释放锁时,会向mysql日志文件写入删除.cfg文件的信息:

2022-03-16T08:08:27.653352Z 10 [Note] InnoDB: Deleting the meta-data file './test/t1#P#p0.cfg'
2022-03-16T08:08:27.653656Z 10 [Note] InnoDB: Deleting the meta-data file './test/t1#P#p1.cfg'
2022-03-16T08:08:27.654214Z 10 [Note] InnoDB: Deleting the meta-data file './test/t1#P#p2.cfg'
2022-03-16T08:08:27.654256Z 10 [Note] InnoDB: Resuming purge

7.在目标实例上,导入表空间:

mysql> select * from t1;
ERROR 1814 (HY000): Tablespace has been discarded for table 't1'
mysql> alter table t1 discard tablespace;
Query OK, 0 rows affected (0.09 sec)

mysql> alter table t1 import tablespace;
Query OK, 0 rows affected (0.46 sec)

mysql> select * from t1;
+------+
| i    |
+------+
|    4 |
|    5 |
|    1 |
|    6 |
|    7 |
|    2 |
|    3 |
|    8 |
|    9 |
+------+
9 rows in set (0.01 sec)

MySQL 传输表空间

将file-per-table表空间复制到另一个实例
如何将一个file-per-table表空间从一个MySQL实例复制到另一个实例中,也就是众所周知的可传输表空间特性。

有很多原因可以解释为什么你可以将一个InnoDB文件表空间复制到不同的实例中:
.在不增加生产服务器额外负载的情况下运行报表。

.在新的从服务器上为表设置相同的数据

.在出现问题或错误后恢复表或分区的备份版本。

.作为一种比mysqldump命令导入更快的移动数据的方法。数据立即可用,而不需要重新插入和重建索引

.将每个file-per-table表空间移动到具有更适合系统需求的存储介质的服务器。例如,您可能希望在SSD设备上有繁忙的表,或者在高容量HDD设备上有大型表。

限制和使用说明
.只有当innodb_file_per_table设置为ON(默认设置)时,才可以拷贝表空间。驻留在共享系统表空间中的表不能被静默。

.当一个表被静默时,只允许在受影响的表上执行只读事务

.在导入表空间时,页面大小必须与导入实例的页面大小相匹配。

.当foreign_key_checks设置为1时,对于父-子(主-外键)关系的表空间不支持DISCARD TABLESPACE。在丢弃父-子表的表空间之前,设置foreign_key_checks=0。分区InnoDB表不支持外键。

.ALTER TABLE……IMPORT TABLESPACE不会对导入的数据强制外键约束。如果表之间存在外键约束,那么所有表都应该在同一(逻辑)时间点导出。分区InnoDB表不支持外键。

.ALTER TABLE……IMPORT TABLESPACE 和 ALTER TABLE…IMPORT PARTITION…TABLESPACE不需要.cfg元数据文件来导入一个表空间。但是,如果导入时没有.cfg文件,则不会执行元数据检查,并且会发出类似于下面的警告:

Message: InnoDB: IO Read error: (2, No such file or directory) Error opening '.\
test\t.cfg', will attempt to import without schema verification
1 row in set (0.00 sec)

在期待没用模式不匹配的情况下,不使用.cfg文件进行导入可能会更方便。此外,在无法从.ibd文件收集元数据的崩溃恢复场景中,不需要.cfg文件就可以导入。

.由于.cfg元数据文件的限制,当为分区表导入表空间文件时,不会对分区类型或分区定义差异报告模式不匹配。列差异被报告。

.当在子分区表上运行ALTER TABLE … DISCARD PARTITION … TABLESPACE和ALTER TABLE … IMPORT PARTITION … TABLESPACE,分区和子分区表名都是允许的。当指定分区名时,该分区的子分区将包含在操作中。

.如果两个实例都有GA(通用可用性)状态,并且它们的版本在同一系列可以从另一个MySQL服务器实例导入表空间文件。否则,该文件必须是在导入它的同一个服务器实例上所创建

.在复制场景中,innodb_file_per_table必须在主节点和从节点上都设置为ON。

.在Windows环境下,InnoDB内部存储数据库、表空间和表名时使用小写字母。为了避免在区分大小写的操作系统(如Linux、UNIX)上的导入问题,请在创建数据库、表空间和表时使用小写名称。一种方便的方法是在创建数据库、表空间或表之前,在my.cnf或my.ini文件的[mysqld]部分中添加下面这一行:

[mysqld]
lower_case_table_names=1

.alter table … discard tablespace和alter table … import tabelspace不支持属于InnoDB通用表空间中的表。

.InnoDB表的默认行格式可以通过innodb_default_row_format配置选项进行配置。如果导入的表没有明确定义行格式(ROW_FORMAT),或者使用了ROW_FORMAT=DEFAULT,那么如果源实例上的innodb_default_row_format设置与目标实例上的innodb_default_row_format设置不一致,可能会导致模式不匹配错误

.在使用InnoDB表空间加密特性导出加密的表空间时,InnoDB除了生成一个.cfg元数据文件外,还会生成一个.cfp文件。在目标实例上执行ALTER TABLE…IMPORT TABLESPACE之前,必须将.cfp文件与.cfg文件和表空间文件一起复制到目标实例中。cfp文件包含一个传输密钥和一个加密的表空间密钥。在导入时,InnoDB使用传输密钥来解密表空间密钥。

传输表空间示例
例如1:复制一个InnoDB表到另一个实例
这个过程演示了如何将一个普通的InnoDB表从一个正在运行的MySQL服务器实例复制到另一个正在运行的实例。可以使用相同的过程在相同的实例上执行全表恢复,只是做了一些小小的调整。
1. 在源实例上,如果不存在表,则创建一个表:

mysql> use test;
Database changed
mysql> create table t(c1 int) engine=innodb;
Query OK, 0 rows affected (0.12 sec)

mysql> insert into t values(1);
Query OK, 1 row affected (0.16 sec)

2.在目标实例上,如果不存在表,则创建表:

mysql> use test;
Database changed
mysql> create table t(c1 int) engine=innodb;
Query OK, 0 rows affected (0.09 sec)

3.在目标实例上,丢弃现有的表空间。(在导入表空间之前,InnoDB必须丢弃连接到接收表空间的表空间。)

[mysql@localhost test]$ ls -lrt
总用量 112
-rw-r-----. 1 mysql mysql    67 3月  15 16:55 db.opt
-rw-r-----. 1 mysql mysql  8556 3月  15 16:57 t.frm
-rw-r-----. 1 mysql mysql 98304 3月  15 16:57 t.ibd

mysql> alter table t discard tablespace;
Query OK, 0 rows affected (0.17 sec)



[mysql@localhost test]$ ls -lrt
总用量 16
-rw-r-----. 1 mysql mysql   67 3月  15 16:55 db.opt
-rw-r-----. 1 mysql mysql 8556 3月  15 16:57 t.frm

4.在源实例上,运行FLUSH TABLES…FOR EXPORT将暂停表并创建.cfg元数据文件

mysql> flush tables t for export;
Query OK, 0 rows affected (0.00 sec)


[mysql@localhost test]$ ls -lrt
总用量 116
-rw-r-----. 1 mysql mysql    67 3月  15 16:53 db.opt
-rw-r-----. 1 mysql mysql  8556 3月  15 16:54 t.frm
-rw-r-----. 1 mysql mysql 98304 3月  15 16:54 t.ibd
-rw-r-----. 1 mysql mysql   371 3月  15 17:00 t.cfg

在InnoDB数据目录下创建元数据(.cfg)
注意:FLUSH TABLES …… FOR EXPORT在MySQL 5.6.6版本中可用。该语句确保对指定表的更改已刷新到磁盘,以便在实例运行时可以生成二进制表副本。当FLUSH TABLES … FOR EXPORT时,InnoDB会在表所在的数据库目录中生成一个.cfg文件。cfg文件中包含导入表空间文件时用于模式验证的元数据。

5.将.ibd文件和.cfg元数据文件从源实例复制到目标实例

[mysql@localhost test]$ scp t.{ibd,cfg} mysql@192.168.1.243:/mysqldata/mysql/test/
mysql@192.168.1.243's password:
t.ibd                                                                                                                                                                                                    100%   96KB  96.0KB/s   00:00
t.cfg                                                                                                                                                                                                    100%  371     0.4KB/s   00:00
[mysql@localhost test]$

在释放共享锁之前必须复制.ibd与.cfg文件。

6.在源实例上,使用unlock tables语句来释放由flush tables … for export所获取的锁:

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

7.在目标实例上,导入表空间:
mysql> alter table t import tablespace;
Query OK, 0 rows affected (0.15 sec)

mysql> desc t;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c1    | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> select * from t;
+------+
| c1   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

可以看到表t从一个实例迁移到另一个实例上。

MySQL InnoDB File-Per-Table表空间

InnoDB File-Per-Table表空间
过去,所有InnoDB表和索引都存储在系统表空间中。这种整体的方法针对的是完全专用于数据库处理的机器,通过精心规划的数据增长,分配给MySQL的任何磁盘存储永远不会被用于其他用途。InnoDB的file-per-table表空间特性提供了一个更灵活的替代方案,每个InnoDB表及其索引都存储在一个单独的.ibd数据文件中。每个这样的.ibd数据文件代表一个单独的表空间。这个特性是由innodb_file_per_table配置选项控制的,在MySQL 5.6.6及更高版本中默认启用。

file-per-table表空间的优点
.当truncate或drop存储在file-per-table表空间中的表时,可以回收磁盘空间。truncate或drop存储在共享系统表空间中的表会在系统表空间数据文件(ibdata文件)内部创建空闲空间,这些空间只能用于新的InnoDB数据。

.在存储在file-per-table表空间文件中的表上运行TRUNCATE TABLE操作会更快。

.您可以将特定的表存储在单独的存储设备上,以实现I/O优化、空间管理或备份目的。在以前的版本中,您必须将整个数据库目录移动到其他驱动器,并在MySQL数据目录中创建符号链接。在MySQL 5.6.6及更高版本中,你可以使用
create table… data directory=absolute_path_to_directory。

.你可以运行OPTIMIZE TABLE来压缩或重新创建一个file-per-table表空间。当你运行一个OPTIMIZE TABLE时,InnoDB会创建一个新的.ibd文件,该文件带有一个临时名称,只使用存储实际数据所需的空间。当优化完成后,InnoDB会删除旧的.ibd文件,并用新文件替换它。如果以前的.ibd文件显著增长,但实际数据只占其大小的一部分,那么运行OPTIMIZE TABLE可以回收未使用的空间。

.你可以移动单个InnoDB表,而不是整个数据库

.你可以将InnoDB表从一个MySQL实例复制到另一个实例(称为可迁移表空间特性)。

.在file-per-table表空间中创建的表使用Barracuda文件格式。Barracuda文件格式支持压缩和动态行格式等特性

.可以使用动态行格式为具有大型BLOB或TEXT列的表启用更高效的存储。

.file-per-table表空间可以在发生损坏、服务器无法重启或备份和二进制日志不可用时提高成功恢复的机会并节省时间。

.在复制或备份表时,file-per-table表空间可以方便地报告每个表的状态。

.可以在文件系统级别监控表大小,而不需要访问MySQL。

.当innodb_flush_method设置为O_DIRECT时,普通的Linux文件系统不允许并发写入单个文件。因此,使用file-per-table表空间和innodb_flush_method可能会提高性能。

.系统表空间存储数据字典和undo日志,受InnoDB表空间大小限制。使用file-per_table表空间,每个表都有自己的表空间,这为增长提供了空间。

file-per-table表空间的潜在缺点
.使用file-per-table表空间,每个表可能有未使用的空间,这些空间只能由同一表的行使用。如果管理不当,可能会造成空间的浪费。

.fsync操作必须在每个打开的表上运行,而不是单个文件上。因为每个文件都有一个单独的fsync操作,所以对多个表的写操作不能合并成一个单独的I/O操作。这可能需要InnoDB执行更多的fsync操作。

.mysqld必须为每个表保留一个打开的文件句柄,如果在file-per-table表空间中有很多表,这可能会影响性能。

.使用了更多的文件描述符

.innodb_file_per_table在MySQL 5.6.6及更高版本中是默认启用的。如果向后兼容MySQL 5.5或5.1是一个问题,你可以考虑禁用它。禁用innodb_file_per_table功能可以防止在ALTER TABLE重新创建InnoDB表(ALGORITHM=COPY)时,阻止alter table将InnoDB表从系统表空间移动到单独的.ibd文件中。

例如,当重构InnoDB表的聚集索引时,表会使用innodb_file_per_table的当前设置重新创建。此行为在添加或删除InnoDB二级索引时不适用。当不重建表而创建二级索引时,无论当前的innodb_file_per_table设置是什么,索引都被存储在与表数据相同的文件中。此行为也不适用于使用CREATE TABLE…TABLESPACE或ALTER TABLE …TABLESPACE语法添加到系统表空间中的表。这些表不受innodb_file_per_table设置的影响。

.如果许多表都在增长,可能会出现更多的碎片,这可能会影响DROP TABLE和表扫描性能。但是,在管理碎片时,将文件放在它们自己的表空间中可以提高性能。

.在删除file-per-table表空间时会扫描缓冲池,对于大小为几十gb的缓冲池来说,这可能需要几秒钟的时间。扫描是用一个宽的内部锁执行的,这可能会延迟其他操作。系统表空间中的表不受影响。

.innodb_autoextend_increment变量定义了自动扩展的共享表空间文件满时的扩展大小(以MB为单位),但不适用于file-per-table表空间文件,不管是否设置了innodb_autoextend_increment,这些文件都是自动扩展的。最初的扩展是少量的,之后扩展以4MB的增量出现。

启用与禁用file-per-table表空间
innodb_file_per_table选项默认是启用的。

为了在启动时设置innodb_file_per_table选项,可以在启动服务时使用–innodb_file_per_table命令行选项或者在my.cnf文件中[mysqld]部分增加以下一行内容:

[mysqld]
innodb_file_per_table=1

你也可以在服务器运行时动态设置innodb_file_per_table:

mysql> SET GLOBAL innodb_file_per_table=1;
Query OK, 0 rows affected (0.00 sec)

启用innodb_file_per_table时,可以将InnoDB表存储在tbl_name.ibd文件。不像MyISAM存储引擎,它有单独的tbl_name.MYD和tbl_name.MYI文件用于索引和数据,InnoDB将数据和索引一起存储在一个.ibd文件中。仍然像往常一样创建tbl_name.frm文件。

如果在启动选项中禁用innodb_file_per_table并重启服务器或者使用set global命令来禁用它,除非你显式的使用create table … tablespace选项将表存放在file-per-table表空间或通用表空间否则innodb将在系统表空间创建新表。

你总是可以读取和写入任何InnoDB表,不管file-per-table设置情况。

如果要将表从系统表空间移动到自己的表空间,需要修改innodb_file_per_table的设置,然后重新创建表:

mysql> SET GLOBAL innodb_file_per_table=1;
mysql> ALTER TABLE table_name ENGINE=InnoDB;

使用CREATE TABLE…TABLESPACE或ALTER TABLE…TABLESPACE语法添加表到系统表空间不受innodb_file_per_table设置的影响。要将这些表从系统表空间移动到file-per-table表空间,必须使用ALTER TABLE…TABLESPACE语法。

InnoDB总是需要系统表空间,因为它把它的内部数据字典和undo日志放在那里。.ibd文件不够InnoDB操作。

当一个表从系统表空间移到它自己的.ibd文件时,组成系统表空间的数据文件保持相同的大小。InnoDB表以前占用的空间可以被新的InnoDB数据重用,但是不会被操作系统回收使用。当将较大的InnoDB表移出系统表空间(磁盘空间有限)时,你可能更喜欢启用innodb_file_per_table并使用mysqldump命令重新创建整个实例。如上所述,使用CREATE TABLE…TABLESPACE或者ALTER TABLE…表空间语法不受innodb_file_per_table设置的影响。这些桌子必须单独移动。

在数据目录外创建逐file-per-table表空间
要在MySQL数据目录之外的特定位置创建一个新的InnoDB file-per-table表空间,使用有data directory = absolute_path_to_directory子句的CREATE TABLE语句的来实现。

提前计划位置,因为您不能在ALTER TABLE语句中使用DATA DIRECTORY子句。您指定的目录可以位于具有特定性能或容量特征的另一个存储设备上,例如快速SSD或大容量HDD。

在目标目录中,MySQL创建一个与数据库名称对应的子目录,在该子目录中为新表创建一个.ibd文件。在MySQL DATADIR目录下的数据库目录中,MySQL创建了一个table_name.Isl文件包含表路径名。.isl文件被MySQL视为一个符号链接。(InnoDB表不支持使用实际的符号链接。)

下面的例子演示了如何在MySQL数据目录外创建一个file-per-table表空间。它显示了在指定目录中创建的.ibd,以及在MySQL数据目录下的数据库目录中创建的.isl。

mysql> use mysql
Database changed
mysql> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set (0.01 sec)


mysql> create table t_cs(c1 int primary key) data directory='/data';
Query OK, 0 rows affected (0.22 sec)


[root@localhost mysql]# pwd
/data/mysql
[root@localhost mysql]# ls -lrt
总用量 96
-rw-r-----. 1 mysql mysql 98304 3月   8 16:09 t_cs.ibd

[root@localhost mysql]# ls -lrt t_cs*
-rw-r-----. 1 mysql mysql 8556 3月   8 16:09 t_cs.frm
-rw-r-----. 1 mysql mysql   20 3月   8 16:09 t_cs.isl

你也可以使用CREATE TABLE…TABLESPACE与DATA DIRECTORY子句结合,在MySQL数据目录之外创建一个file-per-table表空间。为此,你必须指定innodb_file_per_table作为表空间名。

mysql> create table t_cs_3(c1 int primary key) tablespace=innodb_file_per_table data directory='/data';
Query OK, 0 rows affected (0.28 sec)

[root@localhost mysql]# ls -lrt t_cs_2*
-rw-r-----. 1 mysql mysql 98304 3月   8 16:14 t_cs_2.ibd

[root@localhost mysql]# ls -lrt t_cs_2*
-rw-r-----. 1 mysql mysql 8556 3月   8 16:14 t_cs_2.frm
-rw-r-----. 1 mysql mysql   22 3月   8 16:14 t_cs_2.isl

使用这个方法时,你不需要启用innodb_file_per_table。

使用说明:
.MySQL最初保存的.ibd文件是打开的,防止您卸载设备,但如果服务器繁忙,可能最终会关闭表。小心不要在MySQL运行时意外地卸载外部设备,或者在设备断开连接时启动MySQL。当关联的.ibd文件丢失时,试图访问表会导致严重错误,需要重新启动服务器。

如果.ibd文件仍然不在预期的路径上,服务器重启可能会失败。在本例中,手动删除数据库目录中的table_name.isl文件重新启动后,执行DROPTABLE命令删除.frm文件,并从数据字典中删除该表的信息。

.在将表存放在NFS挂载的卷上之前,请查看在使用NFS和MySQL中列出的潜在问题。

.如果您使用LVM快照、文件复制或其他基于文件的机制来备份.ibd文件,请始终使用FLUSH TABLES…FOR EXPORT语句,以确保在备份发生之前将缓存在内存中的所有更改刷新到磁盘。

.DATA DIRECTORY子句是一种支持替代符号链接的方法,符号链接一直存在问题,从来没有被支持用于单独的InnoDB表。

MySQL 修改InnoDB重做日志文件的数量或大小

修改InnoDB重做日志文件的数量或大小
修改你的InnoDB重做日志文件的数量或大小,请执行以下步骤:
1.停止MySQL服务器,并确保它没有错误地关闭

mysql> show variables like 'innodb_log_file%';
+---------------------------+----------+
| Variable_name             | Value    |
+---------------------------+----------+
| innodb_log_file_size      | 50331648 |
| innodb_log_files_in_group | 2        |
+---------------------------+----------+
2 rows in set (0.00 sec)


[root@localhost ~]# service mysqld stop
Shutting down MySQL.... SUCCESS!

2.编辑my.cnf以更改日志文件配置。如果需要修改日志文件大小,请配置innodb_log_file_size。要增加日志文件的数量,可以配置

innodb_log_files_in_group。

[mysql@localhost mysql]$ vi my.cnf
....
innodb_log_file_size=100m
innodb_log_files_in_group=3

3.重新启动MySQL服务器
如果InnoDB检测到innodb_log_file_size大小与重做日志文件大小不同,它会写一个日志检查点,关闭并删除旧的日志文件,创建新的大小的志文件,并打开新的日志文件。

[root@localhost ~]# service mysqld start
Starting MySQL.................................. SUCCESS!


日志文件显示如下:

[mysql@localhost mysql]$ tail -f mysql.err
2022-03-02T02:44:15.775252Z 0 [Warning] Insecure configuration for --secure-file-priv: Current value does not restrict location of generated files. Consider setting it to a valid, non-empty path.
2022-03-02T02:44:15.775476Z 0 [Note] /mysqlsoft/mysql/bin/mysqld (mysqld 5.7.26-log) starting as process 613 ...
2022-03-02T02:44:15.787224Z 0 [Note] InnoDB: PUNCH HOLE support available
2022-03-02T02:44:15.787311Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2022-03-02T02:44:15.787376Z 0 [Note] InnoDB: Uses event mutexes
2022-03-02T02:44:15.787395Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2022-03-02T02:44:15.787411Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2022-03-02T02:44:15.788175Z 0 [Note] InnoDB: Number of pools: 1
2022-03-02T02:44:15.788515Z 0 [Note] InnoDB: Using CPU crc32 instructions
2022-03-02T02:44:15.793577Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2022-03-02T02:44:15.812360Z 0 [Note] InnoDB: Completed initialization of buffer pool
2022-03-02T02:44:15.817437Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2022-03-02T02:44:15.862640Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2022-03-02T02:44:16.043532Z 0 [Warning] InnoDB: Resizing redo log from 2*3072 to 3*6400 pages, LSN=2494312
2022-03-02T02:44:16.169341Z 0 [Warning] InnoDB: Starting to delete and rewrite log files.
2022-03-02T02:44:16.200462Z 0 [Note] InnoDB: Setting log file ./ib_logfile101 size to 100 MB
2022-03-02T02:44:16.200745Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:26.280622Z 0 [Note] InnoDB: Setting log file ./ib_logfile1 size to 100 MB
2022-03-02T02:44:26.281005Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:37.028157Z 0 [Note] InnoDB: Setting log file ./ib_logfile2 size to 100 MB
2022-03-02T02:44:37.029053Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:47.532468Z 0 [Note] InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
2022-03-02T02:44:47.532675Z 0 [Warning] InnoDB: New log files created, LSN=2494312
2022-03-02T02:44:47.533502Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2022-03-02T02:44:47.533760Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2022-03-02T02:44:48.119249Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2022-03-02T02:44:48.121693Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2022-03-02T02:44:48.121740Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2022-03-02T02:44:48.122598Z 0 [Note] InnoDB: Waiting for purge to start
2022-03-02T02:44:48.172771Z 0 [Note] InnoDB: page_cleaner: 1000ms intended loop took 32356ms. The settings might not be optimal. (flushed=0 and evicted=0, during the time.)
2022-03-02T02:44:48.186082Z 0 [Note] InnoDB: 5.7.26 started; log sequence number 2494303
2022-03-02T02:44:48.186431Z 0 [Note] InnoDB: Loading buffer pool(s) from /mysqldata/mysql/ib_buffer_pool
2022-03-02T02:44:48.186776Z 0 [Note] Plugin 'FEDERATED' is disabled.
2022-03-02T02:44:48.366419Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
2022-03-02T02:44:48.367248Z 0 [Warning] CA certificate ca.pem is self signed.
2022-03-02T02:44:48.369110Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2022-03-02T02:44:48.371083Z 0 [Note] IPv6 is available.
2022-03-02T02:44:48.371145Z 0 [Note]   - '::' resolves to '::';
2022-03-02T02:44:48.371213Z 0 [Note] Server socket created on IP: '::'.
2022-03-02T02:44:48.430720Z 0 [Note] InnoDB: Buffer pool(s) load completed at 220302 10:44:48
2022-03-02T02:44:48.434777Z 0 [Note] Failed to start slave threads for channel ''
2022-03-02T02:44:48.452218Z 0 [Note] Event Scheduler: Loaded 0 events
2022-03-02T02:44:48.452566Z 0 [Note] /mysqlsoft/mysql/bin/mysqld: ready for connections.
Version: '5.7.26-log'  socket: '/mysqlsoft/mysql/mysql.sock'  port: 3306  Source distribution

其中以下部分显示了服务器重置日志文件的大小与数量

2022-03-02T02:44:16.043532Z 0 [Warning] InnoDB: Resizing redo log from 2*3072 to 3*6400 pages, LSN=2494312
2022-03-02T02:44:16.169341Z 0 [Warning] InnoDB: Starting to delete and rewrite log files.
2022-03-02T02:44:16.200462Z 0 [Note] InnoDB: Setting log file ./ib_logfile101 size to 100 MB
2022-03-02T02:44:16.200745Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:26.280622Z 0 [Note] InnoDB: Setting log file ./ib_logfile1 size to 100 MB
2022-03-02T02:44:26.281005Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:37.028157Z 0 [Note] InnoDB: Setting log file ./ib_logfile2 size to 100 MB
2022-03-02T02:44:37.029053Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:47.532468Z 0 [Note] InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
2022-03-02T02:44:47.532675Z 0 [Warning] InnoDB: New log files created, LSN=2494312


[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'innodb_log_file%';
+---------------------------+-----------+
| Variable_name             | Value     |
+---------------------------+-----------+
| innodb_log_file_size      | 104857600 |
| innodb_log_files_in_group | 3         |
+---------------------------+-----------+
2 rows in set (0.01 sec)

MySQL 减少InnoDB系统表空间的大小

减少InnoDB系统表空间的大小
不能从系统表空间中删除数据文件。若要减少系统表空间大小,请使用此过程:
1.使用mysqldump将所有的包括MySQL数据库中的InnoDB表dump出来,在5.6当前版本中,包括5张InnoDB表:

[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'innodb_data%';
+-----------------------+------------------------------------+
| Variable_name         | Value                              |
+-----------------------+------------------------------------+
| innodb_data_file_path | ibdata1:76M;ibdata2:50M:autoextend |
| innodb_data_home_dir  |                                    |
+-----------------------+------------------------------------+
2 rows in set (0.01 sec)

mysql> SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql' and ENGINE='InnoDB';
+---------------------------+
| TABLE_NAME                |
+---------------------------+
| engine_cost               |
| gtid_executed             |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| innodb_index_stats        |
| innodb_table_stats        |
| plugin                    |
| server_cost               |
| servers                   |
| slave_master_info         |
| slave_relay_log_info      |
| slave_worker_info         |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
+---------------------------+
19 rows in set (0.00 sec)



[mysql@localhost ~]$ mysqldump  -uroot -pxxzx7817600 --all-databases > all_db_dump_20220223.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.

2.停止MySQL服务器

[mysql@localhost ~]$ mysqladmin -uroot -pxxzx7817600 shutdown
mysqladmin: [Warning] Using a password on the command line interface can be insecure.

3.删除所有已经存在的表空间文件(*.ibd),包括ibdata和ib_log文件。不要忘记删除MySQL数据库中的*.ibd文件。

[mysql@localhost mysql]$ find ./mysql -name "*.ibd"
./mysql/plugin.ibd
./mysql/servers.ibd
./mysql/help_topic.ibd
./mysql/help_category.ibd
./mysql/help_relation.ibd
./mysql/help_keyword.ibd
./mysql/time_zone_name.ibd
./mysql/time_zone.ibd
./mysql/time_zone_transition.ibd
./mysql/time_zone_transition_type.ibd
./mysql/time_zone_leap_second.ibd
./mysql/innodb_table_stats.ibd
./mysql/innodb_index_stats.ibd
./mysql/slave_relay_log_info.ibd
./mysql/slave_master_info.ibd
./mysql/slave_worker_info.ibd
./mysql/gtid_executed.ibd
./mysql/server_cost.ibd
./mysql/engine_cost.ibd
[mysql@localhost mysql]$ find ./mysql -name "*.ibd"    | xargs -n 1 rm -f

[mysql@localhost mysql]$ rm -rf ibdata*
[mysql@localhost mysql]$ rm -rf ib_log*
[mysql@localhost mysql]$ ls -lrt ibdata*
ls: 无法访问ibdata*: 没有那个文件或目录
[mysql@localhost mysql]$ ls -lrt ib_log*
ls: 无法访问ib_log*: 没有那个文件或目录

4.删除InnoDB表的.frm文件

[mysql@localhost mysql]$ rm -rf mysql/plugin..frm
[mysql@localhost mysql]$ rm -rf mysql/servers..frm
[mysql@localhost mysql]$ rm -rf mysql/help_topic..frm
[mysql@localhost mysql]$ rm -rf mysql/help_category..frm
[mysql@localhost mysql]$ rm -rf mysql/help_relation.frm
[mysql@localhost mysql]$ rm -rf mysql/help_keyword.frm
[mysql@localhost mysql]$ rm -rf mysql/time_zone_name.frm
[mysql@localhost mysql]$ rm -rf mysql/time_zone.frm
[mysql@localhost mysql]$ rm -rf mysql/time_zone_transition.frm
[mysql@localhost mysql]$ rm -rf mysql/time_zone_transition_type.frm
[mysql@localhost mysql]$ rm -rf mysql/time_zone_leap_second.frm
[mysql@localhost mysql]$ rm -rf mysql/innodb_table_stats.frm
[mysql@localhost mysql]$ rm -rf mysql/innodb_index_stats.frm
[mysql@localhost mysql]$ rm -rf mysql/slave_relay_log_info.frm
[mysql@localhost mysql]$ rm -rf mysql/slave_master_info.frm
[mysql@localhost mysql]$ rm -rf mysql/slave_worker_info.frm
[mysql@localhost mysql]$ rm -rf mysql/gtid_executed.frm
[mysql@localhost mysql]$ rm -rf mysql/server_cost.frm
[mysql@localhost mysql]$ rm -rf mysql/engine_cost.frm

5.配置一个新表空间

[mysql@localhost mysql]$ vi my.cnf
.......
innodb_data_file_path = ibdata1:10M:autoextend

6.重启MySQL服务器

[root@localhost ~]# service mysqld start
Starting MySQL......... SUCCESS!

7.导入dump文件

[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 < all_db_dump_20220223.sql
mysql: [Warning] Using a password on the command line interface can be insecure.

[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'innodb_data%';
+-----------------------+------------------------+
| Variable_name         | Value                  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:10M:autoextend |
| innodb_data_home_dir  |                        |
+-----------------------+------------------------+
2 rows in set (0.01 sec)

InnoDB系统表空间的文件变回原来的ibdata1了

mysql> SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql' and ENGINE='InnoDB';
+---------------------------+
| TABLE_NAME                |
+---------------------------+
| engine_cost               |
| gtid_executed             |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| innodb_index_stats        |
| innodb_table_stats        |
| plugin                    |
| server_cost               |
| servers                   |
| slave_master_info         |
| slave_relay_log_info      |
| slave_worker_info         |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
+---------------------------+
19 rows in set (0.01 sec)

注意:如果您的数据库只使用InnoDB引擎,那么可能更简单的方法是转储所有数据库,停止服务器,删除所有数据库和InnoDB日志文件,重新启动服务器,并导入转储文件。

MySQL 增加InnoDB系统表空间大小

增加InnoDB系统表空间大小
增加InnoDB系统表空间大小的最简单的方法是从一开始就配置为自动扩展。在表空间定义中为最后一个数据文件指定autoextend属性。当InnoDB用完空间时,会自动增加64MB的文件大小。可以通过设置innodb_autoextend_increment系统变量的值来更改增量大小,该变量以兆字节为单位度量。

mysql> show variables like 'innodb_autoextend_increment';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| innodb_autoextend_increment | 64    |
+-----------------------------+-------+
1 row in set (0.01 sec)

通过添加另一个数据文件,可以按定义的数量扩展系统表空间:
1.关闭MySQL服务器

2.如果上一个数据文件是用autoextend关键字定义的,那么根据它实际增长的大小,将其定义更改为使用固定大小。检查数据文件的大小,将其四舍四入到最接近的1024*1024字节(= 1MB)的倍数,并在innodb_data_file_path中显式指定这个四舍五入的大小。

3.在innodb_data_file_path的末尾添加一个新的数据文件,可以选择使该文件自动扩展。只有innodb_data_file_path中的最后一个数据文件可以被指定为自动扩展。

4.重新启动MySQL服务器。

例如,这个表空间只有一个自动扩展的数据文件ibdata1

mysql> show variables like 'innodb_data%';
+-----------------------+------------------------+
| Variable_name         | Value                  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
| innodb_data_home_dir  |                        |
+-----------------------+------------------------+
2 rows in set (0.00 sec)

假设这个数据文件随着时间的推移增长到76MB。下面是修改原始数据文件以使用固定大小并添加新的自动扩展数据文件后的配置行

innodb_data_home_dir =
innodb_data_file_path =  ibdata1:76M;ibdata2:50M:autoextend

当您向系统表空间配置添加一个新的数据文件时,请确保文件名没有引用现有的文件。当您重启服务器时,InnoDB会创建并初始化该文件

a.关闭MySQL服务器

[root@localhost ~]# service mysqld stop
Shutting down MySQL.. SUCCESS!

b.检查数据文件的大小

[mysql@localhost mysql]$ du -sh ibdata1
76M     ibdata1

c.在innodb_data_file_path的末尾添加一个新的数据文件,可以选择使该文件自动扩展。

innodb_data_file_path =  ibdata1:76M;ibdata2:50M:autoextend

d.重启MySQL服务器

[root@localhost ~]# service mysqld start
Starting MySQL..... SUCCESS!

[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'innodb_data%';
+-----------------------+------------------------------------+
| Variable_name         | Value                              |
+-----------------------+------------------------------------+
| innodb_data_file_path | ibdata1:76M;ibdata2:50M:autoextend |
| innodb_data_home_dir  |                                    |
+-----------------------+------------------------------------+
2 rows in set (0.01 sec)

[root@localhost mysql]# ls -lrt ibdata*
-rw-r-----. 1 mysql mysql 52428800 2月  23 11:13 ibdata2
-rwxr-xr-x. 1 mysql mysql 79691776 2月  23 11:13 ibdata1

MySQL 配置索引页的合并阈值

配置索引页的合并阈值
您可以为索引页配置MERGE_THRESHOLD值。如果一个索引页的“page-full”百分比低于MERGE_THRESHOLD值,当一个行被删除或当一个行被UPDATE 操作缩短时,InnoDB会尝试合并这个索引页和相邻的索引页。默认的MERGE_THRESHOLD值是50,这是以前的硬编码值。MERGE_THRESHOLD最小值为1,最大值为50。

当索引页的页满百分比低于50%(默认的MERGE_THRESHOLD设置)时,InnoDB会尝试将索引页与相邻页合并。如果两个页面都接近50%的满,那么在页面合并后不久就会发生页面分割。如果频繁发生这种合并-分割行为,则会对性能产生不利影响。为了避免频繁的合并分割,你可以降低MERGE_THRESHOLD值,这样InnoDB尝试页面合并的百分比就会降低。以较低的页满百分比合并页面会在索引页中留下更多的空间,并有助于减少合并-分割行为。

可以为一个表或单个索引定义索引页的MERGE_THRESHOLD。为单个索引定义的MERGE_THRESHOLD值优先于为表定义的MERGE_THRESHOLD值。如果未定义,MERGE_THRESHOLD值默认为50。

设置表的MERGE_THRESHOLD
可以使用CREATE TABLE语句的table_option COMMENT子句为一个表设置MERGE_THRESHOLD值。例如:

CREATE TABLE t1 (
id INT,
KEY id_index (id)
) COMMENT='MERGE_THRESHOLD=45';

还可以使用ALTER TABLE的table_option COMMENT子句为现有表设置MERGE_THRESHOLD值

CREATE TABLE t1 (
id INT,
KEY id_index (id)
);

ALTER TABLE t1 COMMENT='MERGE_THRESHOLD=40';

为单个索引设置MERGE_THRESHOLD
要为单个索引设置MERGE_THRESHOLD值,可以使用带有CREATE TABLE、ALTER TABLE或CREATE INDEX的index_option COMMENT子句,如下面的示例所示:
.使用CREATE TABLE为单个索引设置MERGE_THRESHOLD:

mysql> CREATE TABLE t1 (
    -> id INT,
    -> KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40'
    -> );
Query OK, 0 rows affected (0.11 sec)

.使用ALTER TABLE为单个索引设置MERGE_THRESHOLD:

mysql> CREATE TABLE t1 (
    -> id INT,
    -> KEY id_index (id)
    -> );
ALTER TABLE t1 DROP KEY id_index;
ALTER TABLE t1 ADD KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40';Query OK, 0 rows affected (0.17 sec)

mysql> ALTER TABLE t1 DROP KEY id_index;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE t1 ADD KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40';
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

使用CREATE INDEX为单个索引设置MERGE_THRESHOLD:

mysql> CREATE TABLE t1 (id INT);
Query OK, 0 rows affected (0.14 sec)

mysql> CREATE INDEX id_index ON t1 (id) COMMENT 'MERGE_THRESHOLD=40';
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0

不能在索引级别修改GEN_CLUST_INDEX的MERGE_THRESHOLD值,GEN_CLUST_INDEX是InnoDB在创建InnoDB表时,在没有主键或唯一键索引的情况下创建的聚集索引。只能通过设置表的MERGE_THRESHOLD来修改GEN_CLUST_INDEX的MERGE_THRESHOLD值

查询索引的MERGE_THRESHOLD值
当前索引的MERGE_THRESHOLD值可以通过查询INNODB_SYS_INDEXES表获得。例如:

mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE NAME='id_index' \G
*************************** 1. row ***************************
       INDEX_ID: 265
           NAME: id_index
       TABLE_ID: 267
           TYPE: 0
       N_FIELDS: 1
        PAGE_NO: 4
          SPACE: 269
MERGE_THRESHOLD: 40
1 row in set (0.00 sec)

如果使用table_option COMMENT子句显式定义,可以使用SHOW CREATE TABLE查看表的MERGE_THRESHOLD值

mysql> SHOW CREATE TABLE t1 \G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id` int(11) DEFAULT NULL,
  KEY `id_index` (`id`) COMMENT 'MERGE_THRESHOLD=40'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)

在索引级别定义的MERGE_THRESHOLD值优先于为表定义的MERGE_THRESHOLD值。如果未定义,MERGE_THRESHOLD默认为50% (MERGE_THRESHOLD=50,这是以前的硬编码值。

同样,如果使用index_option COMMENT子句显式地定义,也可以使用SHOW INDEX查看索引的MERGE_THRESHOLD值:

mysql> show index from t1 \G
*************************** 1. row ***************************
        Table: t1
   Non_unique: 1
     Key_name: id_index
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment:
Index_comment: MERGE_THRESHOLD=40
1 row in set (0.00 sec)

测量MERGE_THRESHOLD设置的效果:

INNODB_METRICS表提供了两个计数器,可以用来衡量MERGE_THRESHOLD设置对索引页合并的影响。

mysql> SELECT NAME, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME like '%index_page_merge%';
+-----------------------------+----------------------------------------+
| NAME                        | COMMENT                                |
+-----------------------------+----------------------------------------+
| index_page_merge_attempts   | Number of index page merge attempts    |
| index_page_merge_successful | Number of successful index page merges |
+-----------------------------+----------------------------------------+
2 rows in set (0.00 sec)

当降低MERGE_THRESHOLD值时,目标是:
.页面合并尝试和成功合并的次数更少
.尝试合并和成功合并页面的次数相同

太小的MERGE_THRESHOLD设置由于大量的空页面空间导致大量的数据文件。

MySQL 配置InnoDB配置非持久优化器统计信息参数

配置非持久优化器统计信息参数
本节介绍如何配置非持久优化器统计信息。当innodb_stats_persistent=OFF或使用STATS_PERSISTENT=0创建或修改单个表时,优化器统计信息不会被持久化到磁盘。相反,统计信息存储在内存中,并且在服务器关闭时丢失。统计数据还由某些操作在某些条件下定期更新。

从MySQL 5.6.6开始,默认情况下,优化器统计数据被持久化到磁盘上,由innodb_stats_persistent配置选项启用。

优化器数据更新
在以下情况出现时非持久化的优化器统计信息会被更新:
.执行analyze table

.运行show table status,show index,或者在innodb_stats_on_metadata选项被启用时查询information_schema.tables或information_schema.statistics表。

MySQL 5.6.6中,当持久化优化器统计信息被启用时,innodb_stats_on_metadata默认设置为OFF。启用innodb_stats_on_metadata可能会降低具有大量表或索引的模式的访问速度,并降低涉及InnoDB表的查询的执行计划的稳定性。innodb_stats_on_metadata使用SET语句全局配置。set global innodb_stats_on_metadata=ON

innodb_stats_on_metadata只适用于优化器统计信息配置为非持久化(当innodb_stats_persistent被禁用时)。

.启动mysql客户端时启用–auto-rehash选项,这是默认设置。auto-rehash选项会打开所有InnoDB表,打开表的操作会导致统计数据重新计算。为了提高mysql客户端的启动和更新统计信息时间,你可以使用–disable-auto-rehash选项关闭auto-rehash。自动auto-rehash特性允许交互用户自动完成数据库、表和列名的命名。

.表第一次打开。

.InnoDB检测到有1 / 16的表在上次统计数据更新后被修改。

配置采样页面数
MySQL查询优化器使用关于键分布的估计统计信息,根据索引的相对选择性为执行计划选择索引。当InnoDB更新优化器统计数据时,它会从表上的每个索引中随机取样,以估计索引的基数。(这种技术被称为随机潜水。)

为了控制统计信息评估的质量(从而为查询优化器提供更好的信息),可以使用参数innodb_stats_transient_sample_pages更改抽样页面的数量。默认的抽样页面数是8,这可能不足以产生准确的评估,导致查询优化器的索引选择很差。这种技术对于大型表和连接中使用的表尤其重要。对这样的表进行不必要的全表扫描可能会造成严重的性能问题。

当innodb_stats_transient_sample_pages =0时,innodb_stats_persistent的值会影响所有InnoDB表和索引的索引采样。当您更改索引样本大小时,请注意以下潜在的重大影响。
.小值像1或2可以导致不精确的基数评估

.增加innodb_stats_transient_sample_pages的值可能需要更多的磁盘读取。大于8(比如100)的值会导致打开表或执行SHOW table STATUS所需的时间显著放缓。

.优化器可能会根据索引选择性的不同估计选择非常不同的查询计划

无论innodb_stats_transient_sample_pages的值是什么,设置该选项并保持该值。选择一个值,它可以为数据库中的所有表提供合理准确的估计,而不需要过多的I/O。因为除了在执行ANALYZE TABLE时,统计数据会在其他时间自动重新计算,所以增加索引样本大小,运行ANALYZE TABLE,然后再次减少样本大小是没有意义的。

较小的表通常比较大的表需要更少的索引样本。如果你的数据库有很多大的表,考虑使用一个更大的innodb_stats_transient_sample_pages值。

评估InnoDB表analyze table的复杂度
InnoDB表的ANALYZE TABLE复杂度依赖于:
.采样的页面数,由innodb_stats_persistent_sample_pages定义

.表中索引列的数目

.分区数。如果表没有分区,则认为分区数为1。

使用这些参数,估计ANALYZE TABLE复杂度的近似公式是
innodb_stats_persistent_sample_pages的值*表中索引的列数*分区数

通常,结果值越大,ANALYZE TABLE的执行时间就越长

innodb_stats_persistent_sample_pages定义了在全局级别上采样的页面数量。要设置单个表的采样页数,请使用有STATS_SAMPLE_PAGES选项的CREATE TABLE或ALTER TABLE的语句。

如果innodb_stats_persistent=OFF,则由innodb_stats_transient_sample_pages定义采样的页面数

要了解估算ANALYZE TABLE复杂度的更深入的方法,请考虑以下示例:
在大O符号中,ANALYZE TABLE的复杂度被描述为:

O(n_sample
* (n_cols_in_uniq_i
+ n_cols_in_non_uniq_i
+ n_cols_in_pk * (1 + n_non_uniq_i))
* n_part)

.n_sample是采样的页面数(由innodb_stats_persistent_sample_pages定义)

.n_cols_in_uniq_i是所有唯一索引中所有列的总数(不计算主键列)

.n_cols_in_non_uniq_i是所有非唯一索引中所有列的总数

.n_cols_in_pk是主键中的列数(如果没有定义主键,InnoDB会在内部创建一个单列主键)

.n_non_uniq_i是表中非唯一索引的个数

.n_part是分区的数量。如果没有定义分区,则将表视为单个分区。

现在,考虑下面的表(表t),它有一个主键(2列)、一个唯一索引(2列)和两个非唯一索引(各有两列):

mysql> CREATE TABLE t (
    -> a INT,
    -> b INT,
    -> c INT,
    -> d INT,
    -> e INT,
    -> f INT,
    -> g INT,
    -> h INT,
    -> PRIMARY KEY (a, b),
    -> UNIQUE KEY i1uniq (c, d),
    -> KEY i2nonuniq (e, f),
    -> KEY i3nonuniq (g, h)
    -> );
Query OK, 0 rows affected (0.13 sec)

对于上述算法所需的列和索引数据,查询mysql.innodb_index_stats来查看表t的持久索引统计信息。n_diff_pfx%显示了每个索引列的统计信息。
例如,列a和列b用于计算主键索引。对于非唯一索引,除了用户定义的列外,还要统计主键列(a,b)。

mysql> select index_name, stat_name, stat_description
    -> from mysql.innodb_index_stats
    -> where
    -> database_name='mysql' and
    -> table_name='t' and
    -> stat_name like 'n_diff_pfx%';
+------------+--------------+------------------+
| index_name | stat_name    | stat_description |
+------------+--------------+------------------+
| PRIMARY    | n_diff_pfx01 | a                |
| PRIMARY    | n_diff_pfx02 | a,b              |
| i1uniq     | n_diff_pfx01 | c                |
| i1uniq     | n_diff_pfx02 | c,d              |
| i2nonuniq  | n_diff_pfx01 | e                |
| i2nonuniq  | n_diff_pfx02 | e,f              |
| i2nonuniq  | n_diff_pfx03 | e,f,a            |
| i2nonuniq  | n_diff_pfx04 | e,f,a,b          |
| i3nonuniq  | n_diff_pfx01 | g                |
| i3nonuniq  | n_diff_pfx02 | g,h              |
| i3nonuniq  | n_diff_pfx03 | g,h,a            |
| i3nonuniq  | n_diff_pfx04 | g,h,a,b          |
+------------+--------------+------------------+
12 rows in set (0.01 sec)

根据上面显示的索引统计数据和表定义,可以确定以下值:
.n_cols_in_uniq_i,不计算主键列的所有唯一索引中所有列的总数为2 (c和d)

.n_cols_in_non_uniq_i,所有非唯一索引中所有列的总数,为4 (e、f、g和h)

.n_cols_in_pk,主键中的列数是2(a和b)

.n_non_uniq_i,表中非唯一索引的数量为2 (i2nonuniq和i3nonuniq))

.n_part, 分区数,为1

现在可以计算innodb_stats_persistent_sample_pages *(2 + 4 + 2 *(1 + 2)) * 1来确定扫描的叶页数。如果将innodb_stats_persistent_sample_pages设置为默认值20,并将默认的页面大小设置为16 KiB (innodb_page_size=16384),那么你可以估计为表t读取20 * 12 * 16384字节,或者大约4 MiB。

所有4MiB可能不是从磁盘读取的,因为一些叶页可能已经缓存在缓冲池中。