因为一些内容审查方面的原因,一个运行了很久的论坛被要求限期迁移出现有机房。管制很严,要求在1-2天内完成。论坛的文件(主要是图片及附件)100多G,数据库有80G。我评估了一下,导出数据,部署新环境,导入数据,调试到能正常访问,1-2天可能有点紧张,万一迁移不顺利,还得花费更多的时间。但没办法拒绝,先答应下来再说。

如果不想看文字,猛戳此处看视频,临场感更强。

跟其它技术人员讨论了一下,先临时采取投机取巧方式,应付检查,其措施如下:

1、在其它不受内容审核的地区,部署一个代理,用nginx就行。

2、修改现论坛web的监听端口(由80改成8989),暂时先不改,配好nginx反向代理以后,绑定本地hosts,域名指向新部署服务器的ip地址,访问确认没问题,再修改到8989端口。同时代理nginx转发端口也对应改成8989。

3、修改dns,把域名解析到代理web服务器的ip。

这样处理,避开了审查,为迁移赢得了时间。

安排异地机房的技术给我们部署系统,因为经验以及其它方面的原因,花了将近一天的时间才交付过来(幸亏采取了前边的临时措施)。为了加快进度,我们自己做了分工,一人负责新系统部署php、nginx和mysql运行环境,而我负责导出数据。导出数据分两部分:论坛数据本身压缩打包、数据库数据导出再压缩打包。

开始,我习惯性的用mysqldump --all-databases 全库导出,过程很顺利,导出后打包再复制到别的地方,大概2个小时。新系统那边,环境已经部署好了,我试着进行导入,进行了几十分钟,报错,因为中文字符的问题,尝试了几种方式,还是一样,只得放弃。重新回源服务器,换成innobackup导出。悲催的是,这个服务器的系统太老了,为centos 5.8,安装xtrabackup有依赖问题,需要使用yum来处理一些依赖,但系统自带的yum源没有了,只好重新构造了一个Centos-Base.repo,其内容如下:

[base]

name=CentOS-$releasever - Base

#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os

#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/

baseurl=http://vault.centos.org/5.11/os/$basearch/

gpgcheck=1

gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

#released updates

[updates]

name=CentOS-$releasever - Updates

#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates

#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/

baseurl=http://vault.centos.org/5.11/updates/$basearch/

gpgcheck=1

gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

#additional packages that may be useful

[extras]

name=CentOS-$releasever - Extras

#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras

#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/

baseurl=http://vault.centos.org/5.11/extras/$basearch/

gpgcheck=1

gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

#additional packages that extend functionality of existing packages

[centosplus]

name=CentOS-$releasever - Plus

#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus

#baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/

baseurl=http://vault.centos.org/5.11/centosplus/$basearch/

gpgcheck=1

enabled=0

gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

#contrib - packages by Centos Users

[contrib]

name=CentOS-$releasever - Contrib

#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=contrib

#baseurl=http://mirror.centos.org/centos/$releasever/contrib/$basearch/

baseurl=http://vault.centos.org/5.11/contrib/$basearch/

gpgcheck=1

enabled=0

gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

再测试 yum install lrzsz 正常。

从网上下载备份的安装包percona-xtrabackup-2.3.10.tar.gz,用yum 安装libaio-devel、gcc,vim-comm等几个依赖包。另外,在编译该软件是,会提示cmake的版本过低,需要替换一下。

下载cmake-3.9.6.tar.gz,tar开以后,执行 ./configure --prefix=/usr/local/cmake ;make ;make install 把新版本限定到目录/usr/local/cmake,这样就不用处理旧版本,也不会与其产生冲突。编译安装时,带上cmake的全路径:

/usr/local/cmake/bin/cmake -DBUILD_CONFIG=xtrabackup_release && make -j4 

如果出现“CMake Error at cmake/libev.cmake:23 (MESSAGE)”报错信息,手动安装包libev-3.7.tar.gz(yum不到的),步骤为:

tar zxvf libev-3.7.tar.gz

cd libev-3.7

./configure

make;make install

这个不需要指定安装路径,方便cmake执行的时候找得到。

费了好大一通时间,才把这个备份软件安装好,虽然描述得有些啰嗦,但可能对其它人排错会有帮助。

现在,开始切入正题.

执行备份

1、确保源数据库处于启动状态

2、执行指令

innobackupex --user=root --password=MaGiCdB1 --defaults-file=/etc/my.cnf /data1/dumpdir

备份目录是任意足够大的分区

3、检查备份目录,是否产生数据

4、执行 innobackupex --apply-log  /data1/dumpdir/2018-03-30_11-10-53

压缩和传输文件(论坛数据文件与此步骤相同,不再说明)

tar czvf 2018-03-30_11-10-53.tgz  2018-03-30_11-10-53

rsync -avz -e "ssh -p 2222 " 2018-03-30_11-10-53.tgz  120.189.55.109:/data1/

特别值得注意的是,由于数据量比较大,避免shell中断导致任务终止,尽量在screen下进行操作,就算shell退出,也不会受到影响。

到此为止,源服务器的操作暂告一段落。

数据量相对来说比较大,因此传输过程花了好长一段时间。在这同时,在目的服务器,把安装好的环境配置成与源站基本一致(操作系统版本、php、ngnix、mysql做了升级):相同的目录结构、相同的内网ip、相同的用户帐号。这样就可以直接把源站nginx配置、mysql配置、php原样同步过来。目前因为没有数据库数据导入及论坛文件,我先试着在nginx配置的站点根文档写一个php测试脚本test.php,内容为:<? phpinfo(); ?>.把nginx及php服务都启动起来,浏览器访问该url,检查一下php都有哪些模块被加载,与源站是不是差不多的情形。测试完记得删掉它,这个是安全隐患哟!

nginx的主配置文件nginx.conf如下(节录):

user  www www;

worker_processes  8;

#dso {

#     load ngx_http_cache_purge_module.so;

#}

worker_rlimit_nofile 51200;

events {

use epoll;

#use kqueue;   #FreeBSD system

worker_connections 51200;

}

http {

include       mime.types;

....................此处省略.............................

map $request_method $limit {

default         "";

POST            $binary_remote_addr;

}

limit_conn_zone $binary_remote_addr zone=one_limit:10m;

limit_req_zone $limit zone=zone_limit_post:10m rate=10r/m;

log_format post     '$remote_addr - $remote_user [$time_local]  '

'"$request" $status $body_bytes_sent '

'"$http_referer" "$http_user_agent" '

'$host $request_time $proxy_add_x_forwarded_for

$request_body';

access_log /data/logs/http.a.log;

error_log  /data/logs/http.e.log;

#include vhosts/test.conf;

include vhosts/default.conf;

include vhosts/bbs.formyz.net.conf;

include vhosts/file.formyz.net.conf;

}

某个站点的配置文件 bbs.formyz.net.conf

server  {

listen       80;

server_name     bbs.formyz.net;

error_page  404 http://bbs.formyz.net;

access_log /data/logs/bbs.formyz.net-access;

error_log  /data/logs/bbs.formyz.net-error;

limit_conn one_limit 5;

root  /data/html/bbs.formyz.net;

index index.html index.htm  forum.php index.php;

if ($host != 'bbs.formyz.net' ) {

rewrite ^/(.*)$ http://bbs.formyz.net/$1 permanent;

}

if (-d $request_filename) {

rewrite ^/(.*)([^/])$ http://$host:$server_port/$1$2/ permanent;

}

location ^~ /config {

deny all;

}

location ^~ /.git

{

deny all;

}

location ~ /(data|static|template|images|uc_server/data)/.*\.(php|php5|html)?$ {

deny all;

location ~ .*\.(php|php5)$ {

limit_req zone=zone_limit_post burst=5;

if ($request_method = "POST") {

access_log /data/logs/bbs.formyz.net-post post;

}

root    /data/html/bbs.formyz.net;

fastcgi_pass  127.0.0.1:9000;

fastcgi_index index.php;

include fastcgi_params;

}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {

expires      30d;

}

location ~ .*\.(js|css)?$ {

expires      1h;

}

location / {

limit_conn one_limit 5;

rewrite ^(.*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last;

rewrite ^(.*)/article-([0-9]+)\.html$ $1/portal.php?mod=article&articleid=$2 last;

rewrite ^(.*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forum display&fid=$2&page=$3 last;

rewrite ^(.*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last;

rewrite ^(.*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last;

rewrite ^(.*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last;

rewrite ^(.*)/([a-z]+)-(.+)\.html$ $1/$2.php?rewrite=$3 last;

break;

}

}

这里是每一个站点,用一行include 显示的包含。偏偏有不少人,至少我碰到不少,喜欢用 include *.conf把所有的站点都包含进去,我不太赞同这种做法,配置的时候你是方便了,可是到了要维护的时候,就不是那么方便了。为什么这样说?假设现在做维护,我打开nginx.conf大概就可以看到有哪些站点(当然文件命名也要规划好,能望文生义);特别是在一个nginx下站点多的场景,对某个站点进行临时维护,只要在主配置文件nginx.conf注释掉与它关联的include行,重载nginx即可。

接下来给出php-fpm.conf文件的部分内容:

[global]

error_log = log/php-fpm.log

process.max = 5000

rlimit_files = 10240

[www]

user = www

group = www

listen = 127.0.0.1:9000

pm = dynamic

pm.max_children = 5000

pm.start_servers = 50

pm.min_spare_servers = 20

pm.max_spare_servers = 80

pm.max_requests = 5000

access.log = log/php.access.log

slowlog = log/php.log.slow

request_slowlog_timeout = 3

与nginx相对应,php也以普通用户www来运行,同时所有站点目录,都授权属主、属组为www,保证正确与合理的权限。一些经验不足的人,不注意程序权限与目录权限的对应关系,运行服务,只要提示权限不够,就立马执行 chmod -R 777 dir ,你这是在方便别人进入系统呢!另外,php开启了慢查询日志,在运行中排错或者排查性能问题会很有帮助,不过我自己不懂php,一般都是让开发人员自己看这个日志了,他懂的。

把论坛源站复制来的数据文件,tar解包后,放置在nginx指定的目录,然后用chown  -R www:www /data/html 及chmod -R 755 赋权,这个过程比较容易完成,不再赘述。

前边用mysqldump出来的文件,导入失败,这次换成innobackup,根据以往的经验,不应该有问题。注意,用此工具导入时,mysql不要初始化,也不要启动(这个是废话了,没初始化当然不能启动)。为方便大家了解全过程,顺便把mysql的选项文件my.cnf(不叫配置文件哟)贴出来,供大家参考:

[client]

port=3306

socket=/tmp/mysql.sock

[mysqld]

character-set-server=utf8

collation-server=utf8_general_ci

skip-external-locking

skip-name-resolve

user=mysql

port=3306

datadir=/data/mysql_db

open_files_limit=10240

back_log=600

max_connections=500

max_connect_errors=6000

wait_timeout=605800

#open_tables=600

#table_cache = 650

#opened_tables = 630

max_allowed_packet=32M

sort_buffer_size=4M

join_buffer_size=4M

thread_cache_size=300

query_cache_type=1

query_cache_size=256M

query_cache_limit=2M

query_cache_min_res_unit=16k

tmp_table_size=256M

max_heap_table_size=256M

key_buffer_size=256M

read_buffer_size=1M

read_rnd_buffer_size=16M

bulk_insert_buffer_size=64M

lower_case_table_names=1

default-storage-engine=INNODB

innodb_buffer_pool_size=2G

innodb_log_buffer_size=32M

innodb_log_file_size=128M

innodb_flush_method=O_DIRECT

thread_concurrency=32

long_query_time=2

slow-query-log=on

slow-query-log-file=/data/mysql_db/mysql-slow.log

[mysqldump]

quick

max_allowed_packet=32M

按my.cnf指定的"datadir=/data/mysql_db",创建好目录/data/mysql_db,并执行chown -R mysql:mysql /data/mysql 授权。这时,/data/mysql_db目录是空的。如果担心出错,坐好姿势,深呼吸,庄重地敲入screen,然后再执行如下命令行(2018-03-30_11-10-53为源数据库文件解包后的目录):

innobackupex  --defaults-file=/etc/my.cnf --copy-back /data/2018-03-30_11-10-53

这个过程同样比较耗时,没事的话,可以另外再开一个终端,进入目录/data/mysql_db,可以看到不断有目录和文件自动生成。执行完毕且没有报错,基本上就大功告成了。由于安全的原因,mysql对连接帐户有访问限制,迁移到新系统以后,也一样要遵循这个规则。前边已经启动了nginx 和php服务,这里把mysql服务也启动起来。在个人的电脑,绑定windows的hosts文件,把域名与服务器的ip地址临时关联起来,再在浏览器输入域名,提示网页无法访问。已经检查php等配置正确,那么问题就在连接数据库这个上边了。进入论坛根文档(nginx.conf里边root指定的那个),查看连数据库相关的脚本,有好几个呢,其中一个 config_global.php 部分内容为:

.............部分省略....................

$_config = array();

// ----------------------------  CONFIG DB  ----------------------------

- //

$_config['db']['1']['dbhost'] = '172.16.28.94';

$_config['db']['1']['dbuser'] = 'bbs_formyz_net';

$_config['db']['1']['dbpw'] = '5O333EvbY';

$_config['db']['1']['dbcharset'] = 'gbk';

$_config['db']['1']['pconnect'] = '0';

$_config['db']['1']['dbname'] = 'bbs_formyz_net';

$_config['db']['1']['tablepre'] = 'pre_';

$_config['db']['common']['slave_except_table'] = '';

$_config['db']['slave'] = '';

..................................余下省略........................

要解决问题,有两个办法:

(1)跟程序员协作,重新对每一个帐号授权(grant all ...);

(2)在系统上再配置一个 172.16.28.94的ip地址。

搞几天时间了,大家都很累,因此为了省事,我自己做主,在系统的另一个空闲网卡配置了上述私有ip地址。陪完重启网络服务,论坛可以打开,可以登录了。

经过多人多测测试,确认没问题以后,正式做域名解析到新的服务器ip。

还有些工作需要继续完善,包括同步这几天的新数据、开启新的数据备份等。论坛数据用rysnc -e 'ssh -p 20002' -avz src dist同步;数据库稍微麻烦一点,需要临时把论坛停一会,启用主从同步功能。由于源站用innobackup导出数据时,已经记录了主从同步需要的信息(xtrabackup_info),因此同步过程就不需要再执行费时的导出操作,只需按偏移量执行同步就行。

more xtrabackup_info

uuid = 188600e0-33cc-11e8-986b-90b11c180978

name =

tool_name = innobackupex

tool_command = --defaults-file=/etc/my.cnf --user=root --password=... /data/databk/db_back

tool_version = 2.3.10

ibbackup_version = 2.3.10

server_version = 5.5.29-log

start_time = 2018-03-30 11:10:53

end_time = 2018-03-30 11:40:31

lock_time = 0

binlog_pos = filename 'mysql-bin.001258', position '571444300'

innodb_from_lsn = 0

innodb_to_lsn = 79320170996

partial = N

incremental = N

format = file

compact = N

compressed = N

encrypted = N

数据库主从同步完成以后,把slave提升为主。似乎写得太长了,数据库备份部分,就不再写了。

如果不想看文字,猛戳此处看视频,临场感更强。

十年老站吐血迁移实录相关推荐

  1. BUG管理系统(Mantis)迁移实录

    Mantis迁移实录 名词解释 Mantis:  开源的BUG管理平台Mantis,也做MantisBT.           同档次产品有EasyBUG,QC,BugFree,Bugzila. Xa ...

  2. 用typescript完成倒计时_「干货」将数十万行CoffeeScript代码迁移到TypeScript

    作者 | David Goldstein 译者 | 王强 策划 | 小智 转发链接:https://mp.weixin.qq.com/s/TK7kWXX4hR3e-jtpVMuBnw 序言 2017 ...

  3. FreeSql (三十四)CodeFirst 迁移说明

    FreeSql 支持 CodeFirst 迁移结构至数据库,这应该是(O/RM)必须标配的一个功能. 与其他(O/RM)不同FreeSql支持更多的数据库特性,而不只是支持基础的数据类型,这既是优点也 ...

  4. Sql Server之旅——第十二站 sqltext的参数化处理

    Sql Server之旅--第十二站 sqltext的参数化处理 原文:Sql Server之旅--第十二站 sqltext的参数化处理 说到sql的参数化处理,我也是醉了,因为sql引擎真的是一个无 ...

  5. Android程序员如何高薪接私活?十年老炮告诉你,看这一篇就够了

    随着互联网的发展 各大公司接二连三的裁员 前一秒工作安排,后一秒优化通知 搞副业接私活+提升主业技能 该是安卓人该有的觉悟了 都应该要有自己的plan b 尤其是程序员这种远程岗位 一部电脑+技术 就 ...

  6. 计算机系统xp和w7,告诉你十年老电脑装xp还是win7

    现在电脑的设备可谓是越来越多,并且很多家庭也基本都是有多台电脑设备的,但是对于一些老电脑来讲,应该选择什么样的系统去进行重装呢?最近就有小伙伴来问小编说十年老电脑装xp还是win7呢?小编觉得如果是非 ...

  7. 2009年QQ群关系数据库可视化查询器优化推广获客神器十年老数据库

    2009年QQ群关系数据库可视化查询器优化推广获客神器十年老数据库 最近很多人问这个QQ群关系数据库的事儿,拉出来聊一聊,顺带做了部分优化 之前这个是被很多大神玩丢下来的东西,近几年手游市场的兴起,又 ...

  8. 如何选购计算机硬件,DIY攒机经验之谈:十年老司机教你组装电脑如何选购硬件...

    如今,玩游戏的玩家绝大数都是选择组装机,组装机主要优势就是价格便宜,硬件能够按需搭配,不像品牌机,配置方面搭配均衡性很差,往往显卡都是比较低端的,因此在游戏体验会十分不理想.下面装机之家小编分享下十年 ...

  9. 那年十八站在角落如喽啰,如今站在人生巅峰,分享嵌入式求职技巧

    那年十八站在角落如喽啰,如今站在人生巅峰俯瞰人世间,给大家分享嵌入式求职的一些技巧 本人:大方老师,系电气工程研究生,熟悉硬件.STM32单片机.嵌入式Linux. 前言 下面将自己的学习和秋招经验分 ...

最新文章

  1. 基于linux和php的稳定的分布式数据采集架构
  2. 考研数学一2015年真题整理
  3. 【NLP】 深度学习NLP开篇-循环神经网络(RNN)
  4. signal.h 中的宏定义 SIG_DFL 及 SIG_IGN
  5. java6_64.tar配置_centos6.5_64 java 环境变量配置
  6. 谷歌联合 Adobe 发布 Noto 字体【免费下载】
  7. openwrt mt7620 内存大小检测
  8. AIR 窗口,自定义形状窗口,按钮
  9. php70wfpm,CentOS 7 安裝 Nginx、PHP7、PHP-FPM
  10. Phinx - 数据库迁移及版本控制介绍(内含中文文档翻译)
  11. 工业用Linux版本,工业主板支持哪些版本的LINUX系统?
  12. 【ACL2020】使用问题图生成解决multi-hop复杂KBQA
  13. C# WinForm 使用FlowLayoutPanel控件做为导航菜单按钮的容器
  14. Oracle常用函数系列之一:字符函数(1)
  15. MVC中处理表单提交的方式(Ajax+Jquery)
  16. Java实现读Chuck数据
  17. X-FRAME-OPTIONS 出现两个或多个的原因
  18. 【Python爬虫】:使用高性能异步多进程爬虫获取豆瓣电影Top250
  19. 《算法帝国》第一章第二章读书笔记
  20. web html5音乐播放器设计与实现,基于HTML5技术的音乐播放器的设计与实现

热门文章

  1. Linux 进程、父进程、子进程
  2. ux设计中的各种地图_UX设计中的空白
  3. Gitee 如何自动部署博客 Pages?推荐用这个GitHub Actions!
  4. 大型网站技术架构(一)大型网站架构演化
  5. repomd.xml错误14 not found
  6. 程序员制作出价值5亿外卖神器却不能取消订单,你知道吗?
  7. java中文乱码解决之道(五)—–java是如何编码解码的
  8. MVC学习之分页 【转】
  9. JavaScript方法
  10. robotframework(12)修改用户密码(从数据库查询短信验证码)