有个同事需要一个管理系统,需要管理一些图片什么的,我就想着让他用我写的这套系统,然后就想着把代码和库复制一份出来给他用就可以了,然后我顺便可以把一些需要写到配置里的东西提炼下,让这套系统成为一个可复制部署的 CMS 系统。
很熟练的把代码复制一份,nginx 配置复制并修改一份。
3步完成之后,有种莫名的感觉涌上心头,然后打开我的博客,发现里面数据已经空了。。其实我这里使用了Phalcon框架自带的 migrate 功能,但由于 Phalcon 这个功能做的并不好用,并且还需要下载一个工具库,所以第一次部署的时候就直接导出 sql 来搞了。
我系统上的 init.sql 是用 mysqldump 从开发机器上导出的,我一直以为里面只包含建表数据,所以才有了上面的很溜的操作,这一出事很显然就是”我以为“错了,然后查看 init.sql 文件有以下代码。
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `lfuture` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
USE `lfuture`;
--
-- Table structure for table `app_activity_info`
--
DROP TABLE IF EXISTS `app_activity_info`;
欲哭无泪。
mysqldump 导出数据的几种方式。
而我用的就是第三种,这种方式导出的 sql 会去尝试建库切库、删表、新建表、导入数据。
我这个博客刚上线两周,还没有做数据库备份、也没开启binlog,不过幸亏我在 nginx log 里添加了 request_body,而我的博客里目前只有几博客、几条评论,并且博客刚上线两周,我配置的 crontab 去删除30天以前的 nginx 日志也还没起作用,所以说使用日志来恢复是完全没问题了。。
其中一条日志例子(有些敏感信息我替换成了secret)
remote_addr=[218.30.116.3] http_x_forward=[-] time=[20/Jun/2018:10:45:00 +0800] request=[POST /adminApiGate HTTP/1.1] status=[200] byte=[514] elapsed=[0.015] refer=[secrete~~] body=[{\x22module\x22:\x22Dashboard\x22,\x22handler\x22:\x22Statistics\x22,\x22method\x22:\x22statistics\x22}] ua=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36] cookie=[secret] gzip=[-] x_from=[-] msec=[1529462700.279] http_host=[secret] http_accept=[application/json|gzip, deflate, br|zh-CN,zh;q=0.9,en;q=0.8] upstream_response_time=[0.015] sent_http_set_cookie=[-]
用 grep、awk 找出所有的 adminApiGate 的日志的request_body字段(adminApiGate 是后台 api 接口地址)
grep 'adminApiGate' lfutur* |awk -F 'body\=\\[' '{print $2}'|awk -F '] ua' '{print $1}' >/home/work/recovery.data
nginx 默认会把 request_body 转换成16进制,所以直接当成 json 是无法处理的,需要做一步转换,这里使用 PHP 来做,代码如下.
$file = "/Users/liushuai/Downloads/recovery.data";
$saveFile = "/Users/liushuai/Downloads/result.csv";
$fp = fopen($file, 'r');
$csvFp = fopen($saveFile, 'w');
fputcsv($csvFp, array('module', 'handler', 'method', 'payload'));
while ($line =fgets($fp)) {
$pt = 0;
$str = '';
while ($pt < strlen($line)) {
if ($line[$pt] == '\\' && $line[$pt + 1] == 'x') {
$str .= $this->hexToStr($line[$pt + 2]. $line[$pt + 3]);
$pt += 4;
} else {
$str .= $line[$pt];
$pt += 1;
}
}
$result = json_decode($str, true);
$payload = $result['payload']?? [];
fputcsv($csvFp, array($result['module'], $result['handler'], $result['method'], var_export($payload, true)));
}
function hexToStr($hex){
$str="";
for($i=0;$i<strlen($hex)-1;$i+=2)
$str.=chr(hexdec($hex[$i].$hex[$i+1]));
return $str;
}
因为我需要的只是博客、标签的信息,我如果可以拿到 module handler method 字段过滤下就可以,所以我直接把解析结果放到了 csv 文件里,然后筛选,手动入库。
这里有思考如果数据量比较大,可以在日志里取出请求时间,然后对一个资源的 add update接口做排序取最后一条即可,然后直接程序写库。
非著名程序员,全栈开发工程师,长期专注系统开发与架构设计。
功能待开通!
show processlist show processlist 用来查看 MySQL 正在运行的线程,如果使用 root 账号可以看到所有用户的线程或者只能看到所使用账号自己的线程,当然如果该用户被赋予了 Process 权限也是可以查看所有用户的线程的。 命令使用展示: mysql> show processlist; +-----+------+-----------+------+---------+------+----------+------------------+ | Id | User | Host | db | Command | Time | S
常见的数据库主要分为三类,SQL(关系型数据库)、NoSQL(非关系型数据库)、NewSQL。 SQL SQL即关系型数据库(RDBMS — Relational Database Management System),SQL 是基于关系型数据模型设计的数据库,SQL用二维表格表示实体以及实体之间的关系,对数据的操作也几乎全部建立在一个或多个关系表格上,通过对这些关联的表格分组、合并、连接、选取等运算来实现数据库的管理。 常见的关系型数据库有: Orcale MySQL Microsoft SQL server PostgreSQL SQLLite MariaDB 关系型数据库特点 事务性
最近做了一个简单的短链接服务,短链接使用自增 id 转化为 62 进制(10 个数字+26个小写字母+26个大写字母),但是发现插入数据库报了索引插入重复。 展示 创建测试表 CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `short_url` varchar(255) NOT NULL COMMENT '测试', PRIMARY KEY (`id`), UNIQUE KEY `short_url` (`short_url`) ) ENGINE=InnoDB AUTO_INCREMENT
今天要查询一个根据手机号返回用户的姓名,但是想要的 SQL 查询的结果的顺序和 in 后面数组里手机号顺序一样,使用 order by field(phone,111,222) select name,phone from users where phone in (18800000000,18800000000001) order by field(phone, 18800000000,18800000000001)
MySQL修改表的存储引擎有三种方式 alter table 该方式需要执行很长时间 mysql> alter table mytable engine=InnoDB; 导入导出 使用mysqldump导出表,修改导出文件里的create table后面表的名称。 创建新的表。 mysqldump导出的表里会包含drop table,所以要注意!删除该句。防止数据丢失 创建和查询 mysql> create table new_table_name like table_name; mysql> alter table new_table_name engin