博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL初始化过程与源代码分析
阅读量:4172 次
发布时间:2019-05-26

本文共 11558 字,大约阅读时间需要 38 分钟。

MySQL初始化过程与源代码分析

概述

MySQL 在整体架构上分为 Server 层和存储引擎层。

其中 Server 层,包括连接器、查询缓存、分析器、优化器、执行器等,存储过程、触发器、视图和内置函数都在这层实现。数据引擎层负责数据的存储和提取,如 InnoDB、MyISAM、Memory 等引擎。在客户端连接到 Server 层后,Server 会调用数据引擎提供的接口,进行数据的变更。

单点(Single),适合小规模应用,复制(Replication),适合中小规模应用,集群(Cluster),适合大规模应用。

一 mysql二进制与源码目录结构介绍

1.1 MySQL二进制目录

Bin               ----mysql可执行文件

COPYING          ----版权说明文件

Docs              ----mysql文档信息

Include            ----mysql的头文件、

Lib               ----库文件

Man              ----mysql手册信息

README          ----说明文件

Share             -----支持文件

support-files       -----脚本-例如启动脚本

1.2 MySQL源代码目录结构

Boost        -- 是为C++语言标准库提供扩展的一些C++程序库的总称

BUILD                 ----编译安装、一些脚本的目录

Client                -----客户端工具 mysql,mysqladmin

Cmake                 -----编译工具

CMakeLists.txt        -----

cmd-line-utils        ----- 命令行工具 readline,libedit 工具

config.h.cmake        ----- cmake 使用的配置文件

configure.cmake       ----- cmake 使用的配置文件

COPYING               ----- 版权信息

Dbug                  ----- 提供调试用的宏定义

Docs                 ----mysql在不同平台下的参考手册

Doxyfile-perfschema  ---- 第三方组件

Extra                ---- 小工具 如 innochecksum,resolveip

Include              ---- 包含头文件

INSTALL              ---- 安装说明

Libbinlogevents     ----库文件

Libbinlogstandalone    ----库文件

Libevent               ----库文件

Libmysql               ----库文件

Libmysqld              ----库文件

Libservices            ----库文件

Man                    ----帮助手册

mysql-test             ----mysql的测试工具套件

Mysys             ----string,hash等,与跨平台相关的数据结构和算法。

mysys_ssl

Packaging              -—针对不同OS启动停止相关的内容

Plugin                 -- mysgl相关的插件

Rapid                  --与身份认证相关的插件

README                 --说明文档

Regex                  --正则表达式实现,一些源码

Scripts             --提供了一些脚本工具 mysql_install_db/mysqld_safe

Sql                    -- mysql server主要代码的实现,生成mysld文件

sql-common             --存放了部分服务器端和客户端会用到的代码。

Storage                --存储引擎所在的目录

Strings                strings库包含很多字符串处理的函数

support-files         --案例配置文件my .cnf,还有一些其它的脚本和工具

Testclients           --测试文件所有的目录

Unittest              一一单元测试文件

VERSION               一一版本号

Vio                   虚拟I0系统,network io的封闭,一些IO函数

Win                   --在win平台编译所需的文件和一些说明

Zlib                  --zlib算法库

1.2.1 核心

Sql                    -- mysql server主要代码的实现,生成mysld文件

sql-common             --存放了部分服务器端和客户端会用到的代码。

Storage                --存储引擎所在的目录

 

二 mysql源码阅读工具安装与应用

1sourceinsight

2.写字板/记事本UE

3.gdb

2 一般使用notepad++ 就可以了

-- GDB for mysql:

1.识别故障

2.场景重现

3.创建测试案例确认bug

4 定位缺陷根源

5.测试和创建补丁修复bug.

 

--安装GDB

安装OS过程中选择开发包

yum install cmake make gcc gcc-c++ ncurses-devel bison gdb

如果编译安装MYSQL,需要加参教:-DWITH_DEBUG=1

 

 

三 MySQL数据库启动几种方式

mysqld

mysqld_safe

mysql.server

mysqld_mutil

 

3.1 启动方式

3.1 mysqld

  进程被kill以后,不会重启。

mysqld  --defaults-file=/mysql/data/3306/my.cnf --user=mysql &

5082

3.2 mysqld_safe

mysqld_safe是一个shell脚本,调用mysqld命令,进行服务器监听。如果mysqld进程掉了,会自动启mysqld。

mysqld_safe  --defaults-file=/mysql/data/3306/my.cnf --user=mysql &

3.3 mysql.server

mysql.server > mysqld_safe > mysqld服务器程序

service mysql start

service mysql stop

service mysql restart

 

/mysql/app/mysql/support-files里面有mysql.server可以做成启动和停止脚本,也可以做出开机自启动。

需要修改的地方把basedir和datadir修改成争取的参数

basedir=/mysql/app/mysql

datadir=/mysql/data/3306/data

设置pid文件

mysqld_pid_file_path=/mysql/data/3306/mysql.pid

修改启动命令

$bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &

增加启动的参数文件

$bindir/mysqld_safe --defaults-file=/mysql/data/3306/my.cnf    --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &

把文件copy到/etc/init.d/

cp mysql.server /etc/init.d/mysql

制作完脚本以后-总是报错-吧/etc/my.cnf删除解决。

[root@mysql5 3306]# service mysql start

Starting MySQL.The server quit without updating PID file (/[失败]data/3306/mysql.pid).

第一个是 rm -rf /etc/my.cnf

第二个是  $bindir/mysqld_safe  --defaults-file=/mysql/data/3306/my.cnf --datadir="$datadir"  --user=mysql --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &

   是主参数,需要再mysqld_safe以后马上就是。

3.4 windows如何启动和停止

net start mysql

net stop mysql

也可以手工点服务,启动和停止。

 

四 mysql启动过程分析及如何读取配置文件

[root@mysql5 ~]# mysql --verbose --help | grep my.cnf

                      order of preference, my.cnf, $MYSQL_TCP_PORT,

/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf

读取my.cnf顺序,虽然指定了/mysql/data/3306/my.cnf,也会先去读取上面的文件。如果上面已经又配置配件了,就会造成异常。

 

源码:mysys_ssl lmy_default.cc

 

五 mysql启动过程原理分析

MySQL的启动方式通常分成三种:mysqld、mysqld_safe、mysqld_multi(主要用于多实例启动)

 

5.1 三种方式的关系:

首先当我们使用service mysqld start或者/etc/init.d/mysqld start这样的方式启动的时候,其实是使用了mysql.server这个脚本。

这个脚本默认会调用mysqld_safe来启动mysqld,所以通常我们启动mysql之后查看进程的时候会发现有mysqld和mysqld_safe这两个进程存在。

这两种通常都是单实例的启动方式,当然也可以使用mysqld来启动多实例的。

而mysqld_multi用来启动多实例,也是通过先调用mysqld_safe和mysqld来启动mysql的。

5.2 mysql启动分析

默认的mysql的服务启动程序是mysql.server,mysql.server程序主要是会用到两个程序和一个函数,分别是my_print_defaults、 myslqd_safe和parse_server_arguments。

1、my_print_defaultsq读取my.cnf配置文件,输出参数传递给parse_server_arguments,该程序只读my.cnf中[mysqld]中的参数。

2、parse_server_arguments:该函数处理my_print_defaults传递过来的参数赋值给--basedir、--datadir、--pid-file、--server-startup-timeout

3、mysqld_safe:mysqld_safe程序调用mysqld程序来启动mysql服务,[mysqld_safe]会覆盖mysqld部分中的参数

4、mysqld_multi会读取配置文件中的[mysqld_muti],[mysqldN]下面的参数,N需要时一个整数,建议用端口号表示,该部分的配置会覆盖[mysqld]部分中的配置

5、在mysqld进程挂掉的时候,mysqld_safe进程会监测到并重新将mysqld启动起来。

六 mysql.server启动脚本源码阅读与分析

mysql.server主要分3大部分:

变量初始化部分,函数申明部分,具体执行部分

cd /mysql/app/mysql/support-files/

cat /mysql/app/mysql/support-files/mysql.server

 

6.1 变量初始化

指定mysql安装程序及数据的路径,默认是/usr/local/mysql basedir=/mysql/app/mysql

datadir=/mysql/data/3306/data

 

定义mysql服务启动时间的限制,如果超过900S没有启动,脚本会退出。

service_startup_timeout=900

 

判断mysql是否启动

# Set some defaults

mysqld_pid_file_path=/mysql/data/3306/mysql.pid

判断指定目录是否为空

if test -z "$basedir"

then

  basedir=/usr/local/mysql

  bindir=/usr/local/mysql/bin

  if test -z "$datadir"

  then

    datadir=/usr/local/mysql/data

  fi

  sbindir=/usr/local/mysql/bin

  libexecdir=/usr/local/mysql/bin

else

  bindir="$basedir/bin"

  if test -z "$datadir"

  then

    datadir="$basedir/data"

  fi

  sbindir="$basedir/sbin"

  libexecdir="$basedir/libexec"

fi

6.2 函数申明部分

#

# Use LSB init script functions for printing messages, if possible

#

 

# Use LSB init script functions for printing messages, if possible

#

lsb_functions="/lib/lsb/init-functions"

if test -f $lsb_functions ; then

  . $lsb_functions

else

  log_success_msg()

  {

    echo " SUCCESS! $@"

  }

  log_failure_msg()

  {

    echo " ERROR! $@"

  }

Fi

 

首先判断函数是否存在,lsb_functions="/lib/lsb/init-functions"

不存在打印失败。会出现因为linux版本不一样,导致mysql启动失败的案例。可以修改脚本例如把lsb_functions="/lib/lsb/init-functions"变成 lsb_functions="/etc/init.ds/init-functions"  目前还没有遇到,肯定会遇到的。

 

6.3 Mysql脚本start stop restart status执行步骤

  原来的版本

  $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &

 

case "$mode" in

  'start')

    # Start daemon

 

    # Safeguard (relative paths, core dumps..)

    cd $basedir

 

    echo $echo_n "Starting MySQL"

    if test -x $bindir/mysqld_safe

    then

      # Give extra arguments to mysqld with the my.cnf file. This script

      # may be overwritten at next upgrade.

      $bindir/mysqld_safe   --defaults-file=/mysql/data/3306/my.cnf --datadir="$datadir"  --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &

      标红为增加的,正常是没有的。

      wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?

 

      # Make lock for RedHat / SuSE

      if test -w "$lockdir"

      then

        touch "$lock_file_path"

      fi

 

      exit $return_value

    else

      log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)"

    fi

    ;;

 

七 mysqld_safe启动脚本功能及执行流程

7.1 mysqld_safe过程总结

A.检查环境

B检查配置选项

C.启动mysqld及启动后的一些处理

 

 

7.2 mysqld_safe启动的好处

A.安全性相对好

B.启动时指定一些关于mysqld_safe的参数,也可以放在my.cnf里面的[mysqd_safe]下面

C.ulimit -c $core_file_size

D.ulimit -n $size

E 检查环境,检查配置文件,检查指定的选项.

7.3 mysqld_safe参数

[root@mysql5 ~]# mysqld_safe --help

Usage: /mysql/app/mysql/bin/mysqld_safe [OPTIONS]

 The following options may be given as the first argument:

  --no-defaults              Don't read the system defaults file

  --defaults-file=FILE       Use the specified defaults file

  指定的参数文件

  --defaults-extra-file=FILE Also use defaults from the specified file

  不会去用

 

 Other options:

  --ledir=DIRECTORY          Look for mysqld in the specified directory

  --open-files-limit=LIMIT   Limit the number of open files

  --core-file-size=LIMIT     Limit core files to the specified size

  --timezone=TZ              Set the system timezone

  --malloc-lib=LIB           Preload shared library LIB if available

  --mysqld=FILE              Use the specified file as mysqld

  --mysqld-version=VERSION   Use "mysqld-VERSION" as mysqld

  --nice=NICE                Set the scheduling priority of mysqld

  --plugin-dir=DIR           Plugins are under DIR or DIR/VERSION, if

                             VERSION is given

  --skip-kill-mysqld         Don't try to kill stray mysqld processes

  --syslog                   Log messages to syslog with 'logger'

  --skip-syslog              Log messages to error log (default)

  --syslog-tag=TAG           Pass -t "mysqld-TAG" to 'logger'

  --mysqld-safe-log-         TYPE must be one of UTC (ISO 8601 UTC),

    timestamps=TYPE          system (ISO 8601 local time), hyphen

                             (hyphenated date a la mysqld 5.6), legacy

                             (legacy non-ISO 8601 mysqld_safe timestamps)

 

All other options are passed to the mysqld program.

7.4、mysqld_safe流程:

1、查找basedir和ledir.

2、查找datadir和my.cnf。

3、对my.cnf做一些检查,具体检查哪些选项。

4、解析my.cnf中的组[mysqld]和[mysqld_safe]并和终端里输入的命令合并。

5、调用parse_arguments函数解析用户传递的所有参数($)。

6、对系统日志和错误日志的判断和相应处理具体,及选项--err-log参数的赋值。

8、启动mysqld.

7、对选项--user,--pid-file,--socket及--port进行处理及赋值,保证启动时如果不给出这些参数它也会有值。

a)启动时会判断一个进程号是否存在,如果存在那么就在错误日志中记录"A mysqld process already exists"并且退出。

b)如不存在就删除进程文件,如果删除不了,那么就在错误日志中记录"Fatal error:Can't remove the pid file"并退出。

9、启动时对表进行检查。如果启动的时候检查表的话设置key_buffer and sort_buffer会提高速度并且减少磁盘空间的使用。

10、如果启动时你什么参数都没有给,那么它会选用一些特定的参数启动。

11、如果服务器异常关闭,那么会restart。

 

八 mysqld启动与初始化过程源码解析

mysql.server,mysqld_safe,mysqld

九 mysql 关机介绍

9.1 关闭方式

service mysql stop

Shutting down MySQL....                                    [确定]

 

mysqladmin -u root -p shutdown -S /mysql/data/3306/mysql.sock

Enter password:

 

Kill –不建议

9.2 关机过程

1)发起shutdown

2)如果需要是否新建一个关闭线程shutdown thread,如果是客户端发起的关闭,就会建一个专用的关闭线程。

3) mysql server不再响应新的连接请求,关闭tcp/ip网络监听,关闭unix/linux的socket等通道。

4)逐渐关闭当前的连接/事务,空闲将立即被终止

5)mysql server进程关闭所有的线程,关闭所有的存储引擎,innodb会将buffer pool刷新到磁盘中,把当前的LSN记录到表空间中,然后再关所有的内部线程。

6) mysql进程退出

9.3 关机过程-发生阻塞-无意义

Mysql 5.0以上默认是1,1允许快速关闭DB。

show variables like 'innodb_fast%';

+----------------------+-------+

| Variable_name        | Value |

+----------------------+-------+

| innodb_fast_shutdown | 1     |

+----------------------+-------+

1 row in set (0.00 sec)

 

0,代表当MYSQL关闭时,Innodb需要完成所有full purge和merge insert buffer操作,这需要花费时间来完成。如果做Innodb plugin升级,通常需要将这个参数调为0,,然后在关闭数据库

1, 是参数的默认值,不需要完成full purge和merge insert buffer操作,但是在缓冲池的一些数据脏页还是会刷新到磁盘。

2   表示 不需要完成full purge和merge insert buffer操作 ,也不将缓冲池中的数据脏页写回磁盘,。而是将日志都写入日志文件。这样不会有任何事物丢失,但是mysql在下次启动时,会执行恢复操作(recovery)

 

刷脏页75%左右 innodb_max_dirty_pages_pct=0,让innodb把所有的脏页刷新到磁盘中。

show variables like 'innodb_max%';

+--------------------------------+------------+

| Variable_name                  | Value      |

+--------------------------------+------------+

| innodb_max_dirty_pages_pct     | 75.000000  |

| innodb_max_dirty_pages_pct_lwm | 0.000000   |

| innodb_max_purge_lag           | 0          |

| innodb_max_purge_lag_delay     | 0          |

| innodb_max_undo_log_size       | 2147483648 |

+--------------------------------+------------+

 

9.4 关闭不活跃的线程,也就是说术态为slepp,而且time大于1有线程ID。

show processlist;

+----+------+-----------+------+---------+------+----------+------------------+

| Id | User | Host      | db   | Command | Time | State    | Info             |

+----+------+-----------+------+---------+------+----------+------------------+

|  3 | root | localhost | NULL | Query   |    0 | starting | show processlist |

|  4 | root | localhost | NULL | Sleep   |    6 |          | NULL             |

 

mysql> kill 4;

Query OK, 0 rows affected (0.00 sec)

 

9.5 批量杀线程

select concat('KILL ',id, ' ; ') from information_schema.processlist where user='root';

+---------------------------+

| concat('KILL ',id, ' ; ') |

+---------------------------+

| KILL 3 ;                  |

+---------------------------+

1 row in set (0.00 sec)

 

9.6 查询存储引擎状态-确认以下状态

show engine innodb status\G

 

History list length 0

---低于500,也就是没有被purge的事务是不是很少

 

 

Log sequence number 66341939

Log flushed up to   66341939

Pages flushed up to 66341939

Last checkpoint at  66341930

0 pending log flushes, 0 pending chkp writes

如果差值比较大,需要刷表

flush tables;

Query OK, 0 rows affected (0.00 sec)

 

9.7 关机注意

 

如果是salve服务器,最好是先关io线程,等所有的中断日志relay log都应用完了后再sql线程,如果有大事物,一定要等大事务结束后再sql线程。

在关闭mysql服务器。

 

mysql配置文件与参数加载过程

mysql --help | grep my.cnf

    order of preference, my.cnf, $MYSQL_TCP_PORT,

/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf

十一  mysql服务端与客户端连接过程的源码分析

转载地址:http://exbai.baihongyu.com/

你可能感兴趣的文章
无法解析的外部符号的 3 种可能
查看>>
webalizer流量分析软件windows下的配置与使用
查看>>
Java的数组(Array)、Vector、ArrayList、HashMap的异同
查看>>
Apache的使用方法
查看>>
PHP环境配置:Apach+Tomcat+mysql+php
查看>>
CVE-2019-0708漏洞影响面分析及采用多种规则的检测方法
查看>>
拿走不谢!固件逆向分析过程中的工具和技巧(上)
查看>>
整理网络安全措施的5个小技巧
查看>>
入侵win10(下)--渗透系统
查看>>
烦请解释一下“驱动表”的概念
查看>>
IPAide(IP助手) v1.01
查看>>
Oracle 11g RAC SCAN basics
查看>>
ASM appears to be running, but connect via sqlplus, says idle instance.??
查看>>
Oracle EBS R12 - Steps and Issues/Resolutions during R12.1.1 to R12.1.3 Upgration
查看>>
跳过17:30,跳过瑞星定时扫描
查看>>
自动订饭
查看>>
Dos下命令运行带有包名的Java类
查看>>
Tomcat6数据源配置
查看>>
xmove.pl
查看>>
Excel简单五子棋
查看>>