MySQL8 中文参考(二十三)(1)https://developer.aliyun.com/article/1566144
7.8.3 在 Unix 上运行多个 MySQL 实例
原文:
dev.mysql.com/doc/refman/8.0/en/multiple-unix-servers.html
注意
这里的讨论使用 mysqld_safe 来启动多个 MySQL 实例。对于使用 RPM 发行版的 MySQL 安装,在几个 Linux 平台上,服务器的启动和关闭由 systemd 管理。在这些平台上,mysqld_safe 没有安装,因为它是不必要的。有关使用 systemd 处理多个 MySQL 实例的信息,请参见 Section 2.5.9, “Managing MySQL Server with systemd”。
在 Unix 上运行多个 MySQL 实例的一种方法是使用不同的默认 TCP/IP 端口和 Unix 套接字文件编译不同的服务器,以便每个服务器在不同的网络接口上监听。为每个安装编译不同的基目录还会自动为每个服务器生成单独的编译数据目录、日志文件和 PID 文件位置。
假设现有的 5.7 服务器配置为默认的 TCP/IP 端口号(3306)和 Unix 套接字文件(/tmp/mysql.sock
)。要配置一个新的 8.0.36 服务器具有不同的操作参数,可以使用类似以下的 CMake 命令:
$> cmake . -DMYSQL_TCP_PORT=*port_number* \ -DMYSQL_UNIX_ADDR=*file_name* \ -DCMAKE_INSTALL_PREFIX=/usr/local/mysql-8.0.36
这里,port_number
和 file_name
必须与默认的 TCP/IP 端口号和 Unix 套接字文件路径名不同,并且 CMAKE_INSTALL_PREFIX
的值应指定一个安装目录,该目录与现有 MySQL 安装所在的目录不同。
如果您有一个 MySQL 服务器在特定端口号上监听,您可以使用以下命令查找它用于几个重要可配置变量的操作参数,包括基目录和 Unix 套接字文件名:
$> mysqladmin --host=*host_name* --port=*port_number* variables
通过该命令显示的信息,您可以知道在配置额外服务器时不应使用哪些选项值。
如果将 localhost
指定为主机名,mysqladmin 默认使用 Unix 套接字文件而不是 TCP/IP。要明确指定传输协议,请使用 --protocol={TCP|SOCKET|PIPE|MEMORY}
选项。
您无需编译一个新的 MySQL 服务器只是为了使用不同的 Unix 套接字文件和 TCP/IP 端口号开始。也可以使用相同的服务器二进制文件,并在运行时使用不同的参数值启动每个调用。一种方法是使用命令行选项:
$> mysqld_safe --socket=*file_name* --port=*port_number*
要启动第二个服务器,请提供不同的--socket
和 --port
选项值,并通过--datadir=*
dir_name*
选项传递给 mysqld_safe,以便服务器使用不同的数据目录。
或者,将每个服务器的选项放在不同的选项文件中,然后使用--defaults-file
选项启动每个服务器,该选项指定适当选项文件的路径。例如,如果两个服务器实例的选项文件分别命名为 /usr/local/mysql/my.cnf
和 /usr/local/mysql/my.cnf2
,则可以这样启动服务器:命令:
$> mysqld_safe --defaults-file=/usr/local/mysql/my.cnf $> mysqld_safe --defaults-file=/usr/local/mysql/my.cnf2
实现类似效果的另一种方法是使用环境变量设置 Unix 套接字文件名和 TCP/IP 端口号:
$> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock $> MYSQL_TCP_PORT=3307 $> export MYSQL_UNIX_PORT MYSQL_TCP_PORT $> bin/mysqld --initialize --user=mysql $> mysqld_safe --datadir=/path/to/datadir &
这是一个快速启动第二个用于测试的服务器的方法。这种方法的好处是环境变量设置适用于从同一 shell 中调用的任何客户端程序。因此,这些客户端的连接会自动定向到第二个服务器。
Section 6.9, “环境变量” 包括了您可以使用来影响 MySQL 程序的其他环境变量列表。
在 Unix 系统上,mysqld_multi 脚本提供了另一种启动多个服务器的方式。请参阅 Section 6.3.4, “mysqld_multi — 管理多个 MySQL 服务器”。
7.8.4 在多服务器环境中使用客户端程序
原文:
dev.mysql.com/doc/refman/8.0/en/multiple-server-clients.html
要连接到一个 MySQL 服务器的客户端程序,该服务器监听的网络接口与编译到您的客户端的不同,您可以使用以下方法之一:
- 使用
--host=*
host_name*
--port=*
port_number*
启动客户端,使用 TCP/IP 连接到远程服务器,使用--host=127.0.0.1
--port=*
port_number*
使用 TCP/IP 连接到本地服务器,或使用--host=localhost
--socket=*
file_name*
连接到本地服务器使用 Unix 套接字文件或 Windows 命名管道。 - 启动客户端时使用
--protocol=TCP
以使用 TCP/IP 进行连接,使用--protocol=SOCKET
以使用 Unix 套接字文件进行连接,使用--protocol=PIPE
以使用命名管道进行连接,或使用--protocol=MEMORY
以使用共享内存进行连接。对于 TCP/IP 连接,您可能还需要指定--host
和--port
选项。对于其他类型的连接,您可能需要指定--socket
选项以指定 Unix 套接字文件或 Windows 命名管道名称,或者指定--shared-memory-base-name
选项以指定共享内存名称。共享内存连接仅在 Windows 上受支持。 - 在 Unix 上,在启动客户端之前,将
MYSQL_UNIX_PORT
和MYSQL_TCP_PORT
环境变量设置为指向 Unix 套接字文件和 TCP/IP 端口号。如果您通常使用特定的套接字文件或端口号,您可以将设置这些环境变量的命令放在您的.login
文件中,以便每次登录时应用。参见第 6.9 节,“环境变量”。 - 在选项文件的
[client]
组中指定默认的 Unix 套接字文件和 TCP/IP 端口号。例如,您可以在 Windows 上使用C:\my.cnf
,或在 Unix 上使用您的主目录中的.my.cnf
文件。参见第 6.2.2.2 节,“使用选项文件”。 - 在 C 程序中,你可以在
mysql_real_connect()
调用中指定套接字文件或端口号参数。你也可以通过调用mysql_options()
让程序读取选项文件。参见 C API 基本函数描述。 - 如果你正在使用 Perl 的
DBD::mysql
模块,你可以从 MySQL 选项文件中读取选项。例如:
$dsn = "DBI:mysql:test;mysql_read_default_group=client;" . "mysql_read_default_file=/usr/local/mysql/data/my.cnf"; $dbh = DBI->connect($dsn, $user, $password);
- 查看第 31.9 节,“MySQL Perl API”。
其他编程接口可能提供类似的功能来读取选项文件。
7.9 调试 MySQL
7.9.1 调试 MySQL 服务器
7.9.2 调试 MySQL 客户端
7.9.3 锁定顺序工具
7.9.4 DBUG 包
本节描述了帮助跟踪 MySQL 中问题的调试技术。
7.9.1 调试 MySQL 服务器
7.9.1.1 为调试编译 MySQL
7.9.1.2 创建跟踪文件
7.9.1.3 使用 WER 与 PDB 创建 Windows 崩溃转储
7.9.1.4 在 gdb 下调试 mysqld
7.9.1.5 使用堆栈跟踪
7.9.1.6 使用服务器日志查找 mysqld 中错误的原因
7.9.1.7 如果遇到表损坏,制作可重现的测试用例
如果您正在使用 MySQL 中非常新的功能,可以尝试使用 --skip-new
选项运行 mysqld(该选项禁用所有新的、潜在不安全的功能)。参见 附录 B.3.3.3,“如果 MySQL 一直崩溃怎么办”。
如果 mysqld 不想启动,请验证您没有干扰设置的 my.cnf
文件!您可以使用 mysqld --print-defaults 检查您的 my.cnf
参数,并通过使用 mysqld --no-defaults … 来避免使用它们。
如果 mysqld 开始占用 CPU 或内存,或者“挂起”,您可以使用 mysqladmin processlist status 查看是否有人执行需要很长时间的查询。如果遇到性能问题或新客户端无法连接的问题,建议在某个窗口中运行 mysqladmin -i10 processlist status。
命令 mysqladmin debug 会将一些关于正在使用的锁、已使用的内存和查询使用情况的信息转储到 MySQL 日志文件中。这可能有助于解决一些问题。即使您没有为调试编译 MySQL,此命令也会提供一些有用的信息!
如果问题是某些表变得越来越慢,您应该尝试使用 OPTIMIZE TABLE
或 myisamchk 优化表。参见 第七章,MySQL 服务器管理。您还应该使用 EXPLAIN
检查慢查询。
你还应该阅读本手册中针对可能在你的环境中独特的问题的特定于操作系统的部分。参见第 2.1 节,“一般安装指导”。
原文:
dev.mysql.com/doc/refman/8.0/en/compiling-for-debugging.html
7.9.1.1 为调试编译 MySQL
如果你遇到了一些非常具体的问题,你可以尝试调试 MySQL。为此,你必须使用-DWITH_DEBUG=1
选项配置 MySQL。你可以通过执行mysqld --help来检查 MySQL 是否已启用调试。如果选项中列出了--debug
,则表示已启用调试。mysqladmin ver还会将mysqld版本列为mysql … --debug。
如果在使用-DWITH_DEBUG=1
CMake 选项配置时,mysqld停止崩溃,那么你可能已经发现了 MySQL 中的编译器错误或定时错误。在这种情况下,你可以尝试使用CMAKE_C_FLAGS
和CMAKE_CXX_FLAGS
CMake 选项添加-g
,而不使用-DWITH_DEBUG=1
。如果mysqld崩溃,你至少可以使用gdb附加到它,或者使用gdb在核心文件上找出发生了什么。
当你为调试配置 MySQL 时,会自动启用许多额外的安全检查功能,用于监视mysqld的健康状况。如果发现了“意外”情况,会将条目写入stderr
,而这会被mysqld_safe重定向到错误日志!这也意味着,如果你在使用源代码分发时遇到了一些意外问题,你应该首先为 MySQL 配置调试。如果你认为自己发现了一个错误,请按照第 1.5 节“如何报告错误或问题”中的说明操作。
在 Windows MySQL 发行版中,默认情况下,mysqld.exe
是使用跟踪文件支持编译的。
7.9.1.2 创建跟踪文件
如果mysqld服务器无法启动或容易崩溃,您可以尝试创建一个跟踪文件来查找问题。
要执行此操作,您必须使用已编译调试支持的mysqld。您可以通过执行 mysqld -V
来检查这一点。如果版本号以 -debug
结尾,则编译时支持跟踪文件。(在 Windows 上,调试服务器的名称为mysqld-debug而不是mysqld。)
在 Unix 上以 /tmp/mysqld.trace
或在 Windows 上以 \mysqld.trace
的方式启动mysqld服务器:
$> mysqld --debug
在 Windows 上,您还应该使用--standalone
标志,以便不将mysqld作为服务启动。在控制台窗口中,使用以下命令:
C:\> mysqld-debug --debug --standalone
之后,您可以在第二个控制台窗口中使用 mysql.exe
命令行工具重现问题。您可以使用mysqladmin shutdown停止mysqld服务器。
跟踪文件可能会变得非常大!要生成较小的跟踪文件,您可以使用类似以下的调试选项:
mysqld --debug=d,info,error,query,general,where:O,/tmp/mysqld.trace
这仅将最有趣的标签信息打印到跟踪文件中。
如果您提交错误报告,请仅将跟踪文件中指示出错位置的那些行添加到错误报告中。如果找不到错误位置,请打开错误报告并将整个跟踪文件上传到报告中,以便 MySQL 开发人员查看。有关说明,请参见第 1.5 节,“如何报告错误或问题”。
跟踪文件是由 Fred Fish 的 DBUG
软件包制作的。请参见第 7.9.4 节,“DBUG 软件包”。
原文:
dev.mysql.com/doc/refman/8.0/en/making-windows-dumps.html
7.9.1.3 使用 WER 与 PDB 创建 Windows 崩溃转储
程序数据库文件(带有后缀pdb
)包含在 MySQL 的ZIP Archive Debug Binaries & Test Suite分发中。这些文件提供了在出现问题时调试 MySQL 安装的信息。这是与标准 MSI 或 Zip 文件分开下载的。
注意
PDB 文件包含在一个名为"ZIP Archive Debug Binaries & Test Suite"的单独文件中。
PDB 文件包含有关mysqld
和其他工具的更详细信息,可以创建更详细的跟踪和转储文件。您可以使用这些文件与WinDbg或 Visual Studio 一起调试mysqld。
有关 PDB 文件的更多信息,请参阅Microsoft Knowledge Base Article 121366。有关可用的调试选项的更多信息,请参阅Windows 调试工具。
要使用 WinDbg,要么安装完整的 Windows 驱动程序套件(WDK),要么安装独立版本。
重要
.exe
和.pdb
文件必须完全匹配(版本号和 MySQL 服务器版本);否则,WinDBG 在尝试加载符号时会报错。
- 要生成一个 minidump
mysqld.dmp
,请在my.ini
中的[mysqld]部分下启用core-file
选项。在进行这些更改后重新启动 MySQL 服务器。 - 创建一个目录来存储生成的文件,例如
c:\symbols
- 使用查找 GUI 或命令行确定您的windbg.exe可执行文件的路径,例如:
dir /s /b windbg.exe
– 一个常见的默认路径是C:\Program Files\Debugging Tools for Windows (x64)\windbg.exe - 启动
windbg.exe
,并将mysqld.exe
、mysqld.pdb
、mysqld.dmp
和源代码的路径传递给它。或者,从 WinDbg GUI 中传递每个路径。例如:
windbg.exe -i "C:\mysql-8.0.36-winx64\bin\"^ -z "C:\mysql-8.0.36-winx64\data\mysqld.dmp"^ -srcpath "E:\ade\mysql_archives\8.0\8.0.36\mysql-8.0.36"^ -y "C:\mysql-8.0.36-winx64\bin;SRV*c:\symbols*http://msdl.microsoft.com/download/symbols"^ -v -n -c "!analyze -vvvvv"
- 注意
Windows 命令行处理器会删除^
字符和换行符,因此请确保空格保持完整。
7.9.1.4 在 gdb 下调试 mysqld
在大多数系统上,你也可以从 gdb 中启动 mysqld 以获取更多信息,如果 mysqld 崩溃。
在 Linux 上,如果你想要调试 mysqld 线程,一些较旧的 gdb 版本必须使用 run --one-thread
。在这种情况下,你一次只能有一个线程处于活动状态。
在 gdb 下运行 MySQL 时,NPTL 线程(Linux 上的新线程库)可能会导致问题。一些症状包括:
- mysqld 在启动过程中挂起(在写入
ready for connections
之前)。 - mysqld 在调用
pthread_mutex_lock()
或pthread_mutex_unlock()
时崩溃。
在这种情况下,在启动 gdb 之前,你应该在 shell 中设置以下环境变量:
LD_ASSUME_KERNEL=2.4.1 export LD_ASSUME_KERNEL
在 gdb 下运行 mysqld 时,你应该使用 --skip-stack-trace
禁用堆栈跟踪,以便在 gdb 中捕获段错误。
使用 --gdb
选项为 mysqld 安装一个 SIGINT
中断处理程序(用于使用 ^C
停止 mysqld 设置断点),并禁用堆栈跟踪和核心文件处理。
如果你一直在 gdb 下进行大量新连接,那么在 gdb 中不释放旧线程的内存,会导致在 gdb 下调试 MySQL 非常困难。你可以通过将 mysqld 的 thread_cache_size
设置为 max_connections
+ 1 的值来避免这个问题。在大多数情况下,只需使用 --thread_cache_size=5'
就会有很大帮助!
如果在 Linux 上 mysqld 因 SIGSEGV 信号而崩溃,你可以使用 --core-file
选项启动 mysqld 以获取核心转储文件。这个核心文件可以用来生成回溯,帮助你找出 mysqld 为何崩溃:
$> gdb mysqld core gdb> backtrace full gdb> quit
参见 Section B.3.3.3, “What to Do If MySQL Keeps Crashing”。
如果你在 Linux 上使用 gdb,你应该在当前目录中安装一个 .gdb
文件,包含以下信息:
set print sevenbit off handle SIGUSR1 nostop noprint handle SIGUSR2 nostop noprint handle SIGWAITING nostop noprint handle SIGLWP nostop noprint handle SIGPIPE nostop handle SIGALRM nostop handle SIGHUP nostop handle SIGTERM nostop noprint
这里是一个调试 mysqld 的示例:
$> gdb /usr/local/libexec/mysqld gdb> run ... backtrace full # Do this when mysqld crashes
将上述输出包含在一个 bug 报告中,你可以按照 Section 1.5, “How to Report Bugs or Problems” 中的说明进行报告。
如果 mysqld 卡住了,你可以尝试使用一些系统工具如 strace
或 /usr/proc/bin/pstack
来查看 mysqld 卡在哪里。
strace /tmp/log libexec/mysqld
如果你正在使用 Perl DBI
接口,可以通过使用 trace
方法或设置 DBI_TRACE
环境变量来打开调试信息。
7.9.1.5 使用堆栈跟踪
在一些操作系统上,如果mysqld意外死机,错误日志中会包含堆栈跟踪。您可以使用这个来找出mysqld死机的地方(也许是为什么)。参见 Section 7.4.2,“错误日志”。要获得堆栈跟踪,您不能使用 gcc 的-fomit-frame-pointer
选项来编译mysqld。参见 Section 7.9.1.1,“为调试编译 MySQL”。
错误日志中的堆栈跟踪看起来像这样:
mysqld got signal 11; Attempting backtrace. You can use the following information to find out where mysqld died. If you see no messages after this, something went terribly wrong... stack_bottom = 0x41fd0110 thread_stack 0x40000 mysqld(my_print_stacktrace+0x32)[0x9da402] mysqld(handle_segfault+0x28a)[0x6648e9] /lib/libpthread.so.0[0x7f1a5af000f0] /lib/libc.so.6(strcmp+0x2)[0x7f1a5a10f0f2] mysqld(_Z21check_change_passwordP3THDPKcS2_Pcj+0x7c)[0x7412cb] mysqld(_ZN16set_var_password5checkEP3THD+0xd0)[0x688354] mysqld(_Z17sql_set_variablesP3THDP4ListI12set_var_baseE+0x68)[0x688494] mysqld(_Z21mysql_execute_commandP3THD+0x41a0)[0x67a170] mysqld(_Z11mysql_parseP3THDPKcjPS2_+0x282)[0x67f0ad] mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0xbb7[0x67fdf8] mysqld(_Z10do_commandP3THD+0x24d)[0x6811b6] mysqld(handle_one_connection+0x11c)[0x66e05e]
如果跟踪的函数名解析失败,跟踪将包含较少信息:
mysqld got signal 11; Attempting backtrace. You can use the following information to find out where mysqld died. If you see no messages after this, something went terribly wrong... stack_bottom = 0x41fd0110 thread_stack 0x40000 [0x9da402] [0x6648e9] [0x7f1a5af000f0] [0x7f1a5a10f0f2] [0x7412cb] [0x688354] [0x688494] [0x67a170] [0x67f0ad] [0x67fdf8] [0x6811b6] [0x66e05e]
较新版本的glibc
堆栈跟踪函数也会打印相对于对象的地址。在基于glibc
的系统(Linux)上,插件意外退出的跟踪看起来像这样:
plugin/auth/auth_test_plugin.so(+0x9a6)[0x7ff4d11c29a6]
要将相对地址(+0x9a6
)翻译成文件名和行号,请使用以下命令:
$> addr2line -fie auth_test_plugin.so 0x9a6 auth_test_plugin mysql-trunk/plugin/auth/test_plugin.c:65
addr2line实用程序是 Linux 上binutils
软件包的一部分。
在 Solaris 上,该过程类似。Solaris 的printstack()
已经打印了相对地址:
plugin/auth/auth_test_plugin.so:0x1510
要进行翻译,请使用以下命令:
$> gaddr2line -fie auth_test_plugin.so 0x1510 mysql-trunk/plugin/auth/test_plugin.c:88
Windows 已经打印了地址、函数名和行号:
000007FEF07E10A4 auth_test_plugin.dll!auth_test_plugin()[test_plugin.c:72]
7.9.1.6 使用服务器日志查找mysqld错误原因
在启用了一般查询日志的情况下启动mysqld之前,你应该使用myisamchk检查所有表。参见第七章,MySQL 服务器管理。
如果mysqld死机或挂起,你应该启动启用了一般查询日志的mysqld。参见第 7.4.3 节,“一般查询日志”。当mysqld再次死机时,你可以检查日志文件末尾的查询,看看是哪个查询导致了mysqld死机。
如果使用默认的一般查询日志文件,日志将存储在数据库目录中,文件名为*
host_name*.log
。在大多数情况下,导致mysqld死机的是日志文件中的最后一个查询,但如果可能的话,你应该通过重新启动mysqld并从mysql命令行工具执行找到的查询来验证这一点。如果这样可以,你还应该测试所有未完成的复杂查询。
你也可以尝试对所有执行时间较长的SELECT
语句使用EXPLAIN
命令,以确保mysqld正确使用索引。参见第 15.8.2 节,“EXPLAIN 语句”。
通过启用慢查询日志,你可以找到执行时间较长的查询。参见第 7.4.5 节,“慢查询日志”。
如果在错误日志中找到文本mysqld restarted
(通常是一个名为*
host_name*.err
的文件),那么你可能已经找到了导致mysqld失败的查询。如果发生这种情况,你应该使用myisamchk检查所有表(参见第七章,MySQL 服务器管理),并测试 MySQL 日志文件中的查询是否有失败的情况。如果找到这样的查询,首先尝试升级到最新的 MySQL 版本。如果这没有帮助,请报告一个 bug,参见第 1.5 节,“如何报告错误或问题”。
如果你使用myisam_recover_options
系统变量启动了mysqld,MySQL 会自动检查并尝试修复MyISAM
表,如果它们被标记为’未正确关闭’或’崩溃’。如果发生这种情况,MySQL 会在hostname.err
文件中写入一个条目'Warning: Checking table ...'
,接着是Warning: Repairing table
,如果需要修复表。如果你在mysqld在意外死机之前没有出现大量这些错误,那么可能出现了问题,需要进一步调查。参见 Section 7.1.7, “Server Command Options”。
当服务器检测到MyISAM
表损坏时,它会将额外信息写入错误日志,例如源文件的名称和行号,以及访问该表的线程列表。例如:Got an error from thread_id=1, mi_dynrec.c:368
。这是在错误报告中包含的有用信息。
如果mysqld意外死机,这并不是一个好兆头,但在这种情况下,你不应该调查Checking table...
的消息,而是应该尝试找出mysqld为何死机。
原文:
dev.mysql.com/doc/refman/8.0/en/reproducible-test-case.html
7.9.1.7 创建测试用例,如果您遇到表格损坏
以下过程适用于MyISAM
表格。有关遇到InnoDB
表格损坏时应采取的步骤的信息,请参阅第 1.5 节“如何报告错误或问题”。
如果遇到损坏的MyISAM
表格,或者mysqld在一些更新语句后总是失败,您可以通过以下方式测试问题是否可重现:
- 使用mysqladmin shutdown停止 MySQL 守护程序。
- 备份表格以防修复出现问题的极小可能性。
- 使用myisamchk -s database/*.MYI检查所有表格。使用myisamchk -r database/
table
.MYI修复任何损坏的表格。 - 备份表格的第二份备份。
- 如果需要更多空间,请删除(或移动)MySQL 数据目录中的任何旧日志文件。
- 启动mysqld并启用二进制日志。如果要找到导致mysqld崩溃的语句,还应该启用常规查询日志。请参阅第 7.4.3 节“常规查询日志”和第 7.4.4 节“二进制日志”。
- 当您遇到崩溃的表格时,停止mysqld服务器。
- 恢复备份。
- 重新启动mysqld服务器,不启用二进制日志。
- 使用mysqlbinlog binary-log-file | mysql重新执行语句。二进制日志保存在 MySQL 数据库目录中,名称为
hostname-bin.*
NNNNNN*
。 - 如果表格再次损坏或者您可以通过上述命令使mysqld停止运行,那么您已经找到了一个可重现的错误。按照第 1.5 节“如何报告错误或问题”中给出的说明,将表格和二进制日志通过 FTP 上传到我们的错误数据库。如果您是支持客户,您可以使用 MySQL 客户支持中心(
www.mysql.com/support/
)通知 MySQL 团队有关问题,并尽快修复。
MySQL8 中文参考(二十三)(3)https://developer.aliyun.com/article/1566147