标签归档:linux

ECS Kill Mysql 原因排查

问题排查及原因分析:

1、mysql状态检查:
/etc/init.d/mysqld status
mysql dead but subsys locked
2、mysql日志排查:
mysql数据库的一些日志输出存放位置都是在/var/log这个目录下,其中mysqld.log 这个文件就是我们存放我们跟mysql数据库进行操作而产生的一些日志信息,通过查看该日志文件,我们可以从中获得很多信息:
3、messages日志检查:
同样是/var/log这个目录下,通过这个日志的查看:
kernel: Out of memory: Kill process 1078 (mysqld) score 60 or sacrifice child;
kernel: Killed process 1078, UID 27, (mysqld) total-vm:924960kB, anon-rss:60316kB, file-rss:952kB
基本可以确定Mysql挂掉是因为内存的不足的问题,但是为什么突然之间内存不足,需要继续排查:

ECS上站点数据库链接不可用

今天突然发现两个网站都没法访问了,网站用的是阿里云的ECS,之前好像也出现过一次。然后登上去检查了一下访问日志,程序文件有没有变更。。都没有发现什么问题。然后尝试重启Mysql

[code]mysql dead but subsys locked[/code]

查看日志以后发现( 22:12:50是我手动重启了):

[code]

161208 16:35:05 mysqld_safe Number of processes running now: 0
161208 16:35:05 mysqld_safe mysqld restarted
161208 16:35:07 [Note] Plugin ‘FEDERATED’ is disabled.
161208 16:35:07 InnoDB: The InnoDB memory heap is disabled
161208 16:35:07 InnoDB: Mutexes and rw_locks use GCC atomic builtins
161208 16:35:07 InnoDB: Compressed tables use zlib 1.2.3
161208 16:35:07 InnoDB: Using Linux native AIO
161208 16:35:07 InnoDB: Initializing buffer pool, size = 128.0M
InnoDB: mmap(137363456 bytes) failed; errno 12
161208 16:35:07 InnoDB: Completed initialization of buffer pool
161208 16:35:07 InnoDB: Fatal error: cannot allocate memory for the buffer pool
161208 16:35:07 [ERROR] Plugin ‘InnoDB’ init function returned error.
161208 16:35:07 [ERROR] Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed.
161208 16:35:07 [ERROR] Unknown/unsupported storage engine: InnoDB
161208 16:35:07 [ERROR] Aborting
161208 16:35:07 [Note] /usr/libexec/mysqld: Shutdown complete
161208 16:35:08 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
161208 22:12:50 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql

[/code]

问题已经提交论坛求助,后续更新解决方案及问题原因。

git submodule的使用及常见问题

开发过程中,经常会使用一些通用的代码或者组件,但是公共代码库的版本管理是个麻烦的事情,但是submodule的使用可以很好地解决这个问题。

1、添加submodule,命令如下
git submodule add 仓库地址 路径
其中,仓库地址是指子模块仓库地址,路径指将子模块放置在当前工程下的路径。
注意:路径不能以 / 结尾(会造成修改不生效)、不能是现有工程已有的目录(不能順利 Clone)
命令执行完成,会在当前工程根路径下生成一个名为“.gitmodules”的文件,其中记录了子模块的信息。添加完成以后,再将子模块所在的文件夹添加到工程中即可。

2、使用submodule:
正常clone项目
git clone https://github.com/aaaa/bbbb
这个时候进入clone出来的目录,submodule的子目录下面是空的,默认不会把submodule一同checkout出来。
接着需要执行两条命令
git submodule init
git submodule update
这个时候submodule才会正常Checkout出来。

3、删除submodule
submodule的删除稍微麻烦点:首先,要在“.gitmodules”文件中删除相应配置信息。然后,执行“git rm –cached ”命令将子模块所在的文件从git中删除。
下载的工程带有submodule
当使用git clone下来的工程中带有submodule时,初始的时候,submodule的内容并不会自动下载下来的,此时,只需执行如下命令:
git submodule update –init –recursive
即可将子模块内容下载下来后工程才不会缺少相应的文件。

4、更新submodule的坑
submodule项目和它的父项目本质上是2个独立的git仓库。只是父项目存储了它依赖的submodule项目的版本号信息而已。如果你的同事更新了submodule,然后更新了父项目中依赖的版本号。你需要在git pull之后,调用 git submodule update来更新submodule信息。
这儿的坑在于,如果你git pull之后,忘记了调用 git submodule update,那么你极有可能再次把旧的submodule依赖信息提交上去。对于那些习惯使用 git commit -a的人来说,这种危险会更大一些。所以建议大家:
1.git pull之后,立即执行git status, 如果发现submodule有修改,立即执行git submodule update
2.尽量不要使用 git commit -a, git add命令存在的意义就是让你对加入暂存区的文件做二次确认,而 git commit -a相当于跳过了这个确认过程。
更复杂一些,如果你的submodule又依赖了submodule,那么很可能你需要在git pull 和 git submodule update之后,再分别到每个submodule中再执行一次git submodule update,这里可以使用 git submodule foreach命令来实现: git submodule foreach git submodule update

5、修改submodule的坑
有些时候你需要对submodule做一些修改,很常见的做法就是切到submodule的目录,然后做修改,然后commit和push。
这里的坑在于,默认git submodule update并不会将submodule切到任何branch,所以,默认下submodule的HEAD是处于游离状态的(‘detached HEAD’ state)。所以在修改前,记得一定要用git checkout master将当前的submodule分支切换到master,然后才能做修改和提交。

如果你不慎忘记切换到master分支,又做了提交,可以用cherry-pick命令挽救。具体做法如下:
1.用 git checkout master 将HEAD从游离状态切换到 master 分支, 这时候,git会报Warning说有一个提交没有在branch上,记住这个提交的change-id(假如change-id为 aaaa)
2.用 git cherry-pick aaaa 来将刚刚的提交作用在master分支上
3.用 git push 将更新提交到远程版本库中

自定义Mysql的data目录

论坛再次进行迁移,第一次从window迁移到linux,具体可参照Discuz!X3 window迁移到linux。时隔一年,虚拟主机的性能各方面都不如意,加上现在云主机价格的优势,果断选择了云主机。当时考虑了阿里云的腾讯云两个产品,当前网站使用的是阿里云主机,所以也想体验一下腾讯云主机,加上优惠政策选了一台腾讯云香港主机。

流程基本一致,打包文件传到新机器上面,新机器做好环境配置。从控制台比较腾讯云比阿里云还是有一定的差距,如果有兴趣你可以自己注册一个账号两家对比一下。在打包过程中犯了一次二。打包了db。以为都是centos,db文件拷贝过去应该可以用吧。但是结果是根本不能用。所以回归到最靠谱的操作,导出.sql文件然后再导入。这个过程中还碰到了一个问题,后面会有介绍。

为了操作方便一些,web和db都做了自定义路径。扯了这么多,回到正题自定义Mysql的data目录。

1、在根目录下建立data目录
cd /
mkdir data
mkdir /data/data
mkdir /data/www

2、停止mysql进程
mysql -u root -p shutdown

3、把/var/lib/mysql整个目录移到/data/data
mv /var/lib/mysql /data/data/
这样MySQL的数据文件就移动到了/data/data/mysql下

4、找到my.cnf配置文件
如果/etc/目录下没有my.cnf配置文件,请到/usr/share/mysql/找到my-medium*.cnf文件,拷贝到/etc/并改名为my.cnf
命令如下:
[root@test1 mysql]# cp /usr/share/mysql/my-medium.cnf /etc/my.cnf

5、编辑/etc/my.cnf
为保证MySQL能够正常工作,需要指明mysql.sock文件的产生位置。修改socket=/var/lib/mysql/mysql.sock
socket=/data/data/mysql/mysql.sock
操作如下:
vi   my.cnf
# The MySQL server[mysqld]
port = 3306
#socket  = /var/lib/mysql/mysql.sock(原内容,为了更稳妥用“#”注释此行)
socket  = /data/data/mysql/mysql.sock (加上此行)

6、修改MySQL启动脚本/etc/init.d/mysql
把其中datadir=/var/lib/mysql一行中修改成现在的实际存放路径:data/data/mysql
[root@test1 etc]# vi /etc/init.d/mysql
#datadir=/var/lib/mysql(注释此行)
datadir=/data/data/mysql (加上此行)
最后做一个mysql.sock 链接:
ln -s /data/data/mysql/mysql.sock /var/lib/mysql/mysql.sock(需要从/data/data/mysql下复制一份过来)

7、重新启动MySQL服务
/etc/init.d/mysqld start
或用reboot命令重启Linux
如果工作正常移动就成功了,否则对照前面的7步再检查一下。

8、最后修改下数据库的权限
[root@localhost ~]# chown -R mysql:mysql /data/data/mysql/  ← 改变数据库的归属为mysql

[root@localhost ~]# chmod 700 /data/data/mysql/test/  ← 改变数据库目录属性为700

[root@localhost ~]# chmod 660 /data/data/mysql/test/*  ← 改变数据库中数据的属性为660

9 如果启动不成功,查看/var/log/mysql.log,如果是出现错误:
110222 11:15:07 [Warning] Can’t create test file /data/mysql/localhost.lower-test
/usr/libexec/mysqld: Can’t find file: ‘./mysql/plugin.frm’ (errno: 13)
110222 11:15:07 [ERROR] Can’t open the mysql.plugin table. Please run mysql_upgrade to create it.
110222 11:15:07 InnoDB: Operating system error number 13 in a file operation.
InnoDB: The error means mysqld does not have the access rights to

#在终端中先输入下面这一行

chown -R mysql:mysql /data/data/mysql

#在输入下面的一行就OK了

chcon -R -t mysqld_db_t /data/data/mysql

#重启下MYSQL试试~

/etc/init.d/mysqld restart