DB MySQL
2019-02-01
partition_options:
PARTITION BY
{ [LINEAR] HASH(expr)
| [LINEAR] KEY [ALGORITHM={1 | 2}] (column_list)
| RANGE{(expr) | COLUMNS(column_list)}
| LIST{(expr) | COLUMNS(column_list)} }
[PARTITIONS num]
[SUBPARTITION BY
{ [LINEAR] HASH(expr)
| [LINEAR] KEY [ALGORITHM={1 | 2}] (column_list) }
[SUBPARTITIONS num]
]
[(partition_definition [, partition_definition] ...)]
partition_definition:
PARTITION partition_name
[VALUES
{LESS THAN {(expr | value_list) | MAXVALUE}
|
IN (value_list)}]
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string' ]
[DATA DIRECTORY [=] 'data_dir']
[INDEX DIRECTORY [=] 'index_dir']
[MAX_ROWS [=] max_number_of_rows]
[MIN_ROWS [=] min_number_of_rows]
[TABLESPACE [=] tablespace_name]
[(subpartition_definition [, subpartition_definition] ...)]
subpartition_definition:
SUBPARTITION logical_name
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string' ]
[DATA DIRECTORY [=] 'data_dir']
[INDEX DIRECTORY [=] 'index_dir']
[MAX_ROWS [=] max_number_of_rows]
[MIN_ROWS [=] min_number_of_rows]
[TABLESPACE [=] tablespace_name]
分区类型
[LINEAR] HASH(expr)
根据值的哈希分区
[LINEAR] KEY [ALGORITHM={1 | 2}] (column_list)
RANGE{(expr) | COLUMNS(column_list)}
根据值得范围分区
LIST{(expr) | COLUMNS(column_list)}
根据不同的值分区
COLUMNS 不限于整数
创建分区
PARTITION BY LIST(column) (
PARTITION a VALUES IN (a1, a2, a3),
PARTITION b VALUES IN (b1, b2, b3),
PARTITION c VALUES IN (c1, c2, c3)
)
PARTITION BY RANGE(column) (
PARTITION 2012q1 VALUES LESS THAN('2012-04-01'),
PARTITION 2012q2 VALUES LESS THAN('2012-07-01'),
PARTITION 2012q3 VALUES LESS THAN('2012-10-01'),
PARTITION 2012q4 VALUES LESS THAN('2013-01-01')
)
PARTITION BY HASH(column) PARTITIONS 128
PARTITION BY HASH(dayofmonth(date)) PARTITIONS 31
查看分区信息
SELECT * FROM `information_schema`.`PARTITIONS`;
子分区
PARTITION
关键字换成 SUBPARTITION
,PARTITIONS
关键字换成 SUBPARTITIONS
,接在分区语句后面。
- 可以是不同类型。
比如:
PARTITION BY HASH (prod_id) SUBPARTITION BY HASH (cust_id)
PARTITIONS 4 SUBPARTITIONS 4;
脚本
如果是 By Range 分区,一般需要自动创建新的分区,删除久的分区。
比如:
CREATE TABLE `test` (
`id` INT NOT NULL AUTO_INCREMENT,
`date` DATE NOT NULL,
`key` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
`value` VARCHAR(300) NOT NULL COLLATE 'utf8mb4_general_ci',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`, `date`) USING BTREE,
UNIQUE INDEX `key` (`date`, `key`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
/*!50100 PARTITION BY RANGE (to_days(`date`))
(PARTITION p20230123 VALUES LESS THAN (738909) ENGINE = InnoDB,
PARTITION p20230124 VALUES LESS THAN (738910) ENGINE = InnoDB,
PARTITION p20230125 VALUES LESS THAN (738911) ENGINE = InnoDB) */;
然后,通过下面这个 cron 任务自动更新分区:
#!/bin/bash
# 开启调试模式,输出每条执行的命令及其执行结果
set -x
# 检查当前机器 IP 地址中是否包含指定的 VIP(虚拟 IP)
# 确认在主 MySQL 上执行
vip_w="192.168.12.34"
if [ $(/sbin/ip a | grep "${vip_w}" | wc -l) -eq 0 ]; then echo 'WARN: Wrong Machine!!!'; exit 1; fi
# 删除 90 天前的分区
# PS:如果分区不存在,TRUNCATE 不会报错。
delete_date=$(date -d '90 days ago' +%Y%m%d)
mysql -uroot -p123456 -e "USE test; ALTER TABLE test TRUNCATE PARTITION p$delete_date;" # DROP
# 创建未来分区
create_date=$(date -d '7 days' +%Y%m%d)
mysql -uroot -p123456 -e "USE test; ALTER TABLE test ADD PARTITION (PARTITION p$delete_date VALUES LESS THAN (TO_DAYS("$delete_date")));"
PuTTY
2019-01-30
参考:https://github.com/altercation/solarized/blob/master/putty-colors-solarized/solarized_dark.reg
Colour21\255,255,255\
Colour20\187,187,187\
Colour19\85,255,255\
Colour18\0,187,187\
Colour17\255,85,255\
Colour16\187,0,187\
Colour15\85,85,255\
Colour14\0,0,187\
Colour13\255,255,85\
Colour12\187,187,0\
Colour11\85,255,85\
Colour10\0,187,0\
Colour9\255,85,85\
Colour8\187,0,0\
Colour7\85,85,85\
Colour6\0,0,0\
Colour5\0,255,0\
Colour4\0,0,0\
Colour3\85,85,85\
Colour2\0,0,0\
Colour1\255,255,255\
Colour0\187,187,187\
Colour0\131,148,150\
Colour1\147,161,161\
Colour2\0,43,54\
Colour3\7,54,66\
Colour4\0,43,54\
Colour5\238,232,213\
Colour6\7,54,66\
Colour7\0,43,56\
Colour8\220,50,47\
Colour9\203,75,22\
Colour10\133,153,0\
Colour11\88,110,117\
Colour12\181,137,0\
Colour13\101,123,131\
Colour14\38,139,210\
Colour15\131,148,150\
Colour16\211,54,130\
Colour17\108,113,196\
Colour18\42,161,152\
Colour19\147,161,161\
Colour20\238,232,213\
Colour21\253,246,227\
Email
2019-01-14
紧急程度 X-Priority
有另一个 Priority 头,不知道为什么没有使用。
根据网上的一些资料,这几个头已经被垃圾邮件滥用,导致可能会被拦截。
不过,企业邮箱使用应该没有问题。
网易邮箱发送的时候勾选重要
,就会设置 X-Priority: 1
。
需要发送回执 Disposition-Notification-To
效果就是客户端会提示:“是否发送回执”,确认 or 取消。
注意,不是所有客户端会支持回执。
mdn-request-header = "Disposition-Notification-To" ":" 1#mailbox
# mailbox 就是 local-poart@domain 这种格式
# RFC 中的这个 1# 我也不知道是干嘛用的
值是正常的邮件地址格式就行了,比如:
Disposition-Notification-To: admin@example.com
Disposition-Notification-To: =?utf-8?b?566h55CG5ZGY?= admin@example.com
注意:会和 Return-Path 的域名部分做对比,如果不一致,不会发送回执。
参考:https://www.rfc-editor.org/rfc/rfc2298.html
回执参考
主要是有这么一段:
Content-Type: message/disposition-notification; name="MDNPart2.txt"
Content-Disposition: inline
Content-Transfer-Encoding: 7bit
Reporting-UA: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0
Final-Recipient: rfc822;huang@example.com
Original-Message-ID: <2ec11bc0.59a.1803f61e0f9.Coremail.admin@example.com>
Disposition: manual-action/MDN-sent-manually; displayed
参考资料与拓展阅读
Python
2019-01-13
今天研究 secure cookie (安全的 Cookie) 的时候发现这个问题,觉得很好玩,之前还没有遇到过,没有注意。
a = b'hello'
a[0]
# 104
Python3 对 Bytes 类型索引取值返回的是一个整数!!!
这个以后需要小心,如果要像我们预期的那样,取一个字符的话,应该这样:
a = b'hello'
a[0:1]
# h
WebDev Cookie 安全 Tornado
2019-01-13
本文讲的是 Tornado 框架中的 “secure cookie” 实现。
Email
2019-01-10
经过测试,至少 QQ 和 网易邮箱的 WebMail 都提供了日程的支持。
Thunderbird 只能通过日历 App 打开附件 (ics 文件) 的方式添加日程。
效果

原理
在邮件中插入了一个 text/calendar
类型的附件:
Content-Type: text/calendar; charset=utf-8; method=REQUEST;
name=ATT1547083200618.ics
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename="ATT1547083200618.ics"
解析出来这样一个 iCal 文件:
BEGIN:VCALENDAR
PRODID:-//Netease//WebMail
VERSION:2.0
METHOD:REQUEST
BEGIN:VEVENT
SUMMARY:日程:上午十点的面试
LOCATION:小会议室
DTSTART:20190110T013000Z
DTEND:20190110T023000Z
UID:11c27eb7-adab-4549-8aea-efadcec7bb6c
SEQUENCE:0
STATUS:CONFIRMED
ORGANIZER;CN=张三:mailto:zhangsan@example.com
ATTENDEE:mailto:lisi@example.com
END:VEVENT
END:VCALENDAR
回复
这个回复就各异了,没有同意的格式。
QQ 邮件只会有一个 自动回复: xxxx
,不知道是接受还是拒绝。
QQ 企业邮件会有详细的信息,附带了原日程,并有一句话:xxx 已经接受你的邀请: 日程:xxx
。
WebDev 缓存
2019-01-06
Apache,Nginx 都有缓存功能,再加上 Redis 做动态数据的缓存,再加上 CDN,所以我还没有用过专门的缓存服务。
但是这些服务真是大名鼎鼎,即便不用,我也可以先列出来做个简单的了解。
Git
2019-01-03
命令
usage: git submodule [--quiet] [--cached]
or: git submodule [--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
or: git submodule [--quiet] status [--cached] [--recursive] [--] [<path>...]
or: git submodule [--quiet] init [--] [<path>...]
or: git submodule [--quiet] deinit [-f|--force] (--all| [--] <path>...)
or: git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] [--] [<path>...]
or: git submodule [--quiet] set-branch (--default|--branch <branch>) [--] <path>
or: git submodule [--quiet] set-url [--] <path> <newurl>
or: git submodule [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
or: git submodule [--quiet] foreach [--recursive] <command>
or: git submodule [--quiet] sync [--recursive] [--] [<path>...]
or: git submodule [--quiet] absorbgitdirs [--] [<path>...]
相关文件
-
.gitmodules
[submodule "<moduleName>"]
path = <moduleDir>
url = <repoAddr>
-
.git/config 中有相近的 section:
[submodule "<moduleName>"]
active = true
url = <repoAddr>
-
.git
目录在 .git/modules/<moduleName>
克隆
参考:https://stackoverflow.com/questions/3796927/how-to-git-clone-including-submodules
git clone --recurse-submodules -j8 github.com:shouce/shouce.git # 2.13+
git clone --recursive -j8 github.com:shouce/shouce.git # 1.6.5+
-j
表示子模块并发操作,每次 n 个子模块。
针对更老的版本或者以存在的库:
git clone github.com:shouce/shouce.git
cd shouce
git submodule update --init --recursive
发现一个 clone 参数 --[no-]shallow-submodules
,可以使每个子模块仓库的克隆 deepth 为 1,应该是用得上的。
已存在的项目
可能是克隆的时候没有克隆子仓库,也可能是后面添加进来的子仓库。
$ git submodule init
Submodule '<moduleName>' (<repoAddr>) registered for path '<moduleDir>'
$ git submodule update
Cloning into '<moduleFullPath>'...
Submodule path '<moduleDir>': checked out '<commitID>'
或者二合一:
git submodule update --init --recursive
后面有更新就进入子模块 git pull。
添加子模块
git submodule add -b dev --name devtools gitee.com:catroll/devtools tools/dev
# [submodule "devtools"]
# path = tools/dev
# url = gitee.com:catroll/devtools
# branch = dev
删除子模块
$ git submodule deinit <moduleDir>
Cleared directory '<moduleDir>'
Submodule '<moduleName>' (<remoteAddr>) unregistered for path '<moduleDir>'
作用:
- 清空子模块目录下的所有文件
- 去掉 .git/config 子模块配置
这个操作之后:git status
没有任何变化,.gitmodule
还保留着。
然后:
- 修改 .gitmodules
- 删除子模块目录
- 提交变更
- 推送到远程仓库
ORM 软件开发
2019-01-01
:) 本文正在编辑中,暂时不提供浏览...
Python Pipenv Virtualenv Crontab
2018-12-20
部署
# curl: (35) SSL connect error
# StackOverflow: You are using a very old version of curl.
# yum upgrade curl
# 安装 pyenv
curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
# 环境变量
PYENV_ROOT="$HOME/.pyenv"
PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
# 可用版本列表
pyenv install -l
# 使用国内 Python 镜像,相当于给 pyenv 加速
wget https://mirrors.sohu.com/python/3.6.7/Python-3.6.7.tar.xz -P ~/.pyenv/cache/
# 安装(优先使用缓存目录中的文件,会检查缓存校验码是否正确)
pyenv install 3.6.7
运行方式
假定:
- 项目路径:
/path/to/project/
- 定时任务命令:
python main.py
crontab 配置
早上 01:15 执行某某定时任务:
15 1 * * * /bin/bash /path/to/project/cron.sh
脚本 cron.sh
pyenv + pip 模式
#!/bin/bash
# 环境变量
PYENV_ROOT="$HOME/.pyenv"
PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
cd /path/to/project/
# 创建并激活虚拟环境,安装依赖
# $PYENV_ROOT/versions/3.6.7/envs/tasks/
pyenv virtualenv 3.6.7 tasks
if [ $? -ne 0 ]; then
pyenv activate tasks
pip install -r requirements.txt
else
pyenv activate tasks
fi
# 运行脚本
python main.py
pyenv + pipenv 模式
#!/bin/bash
# 环境变量
PYENV_ROOT="$HOME/.pyenv"
PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
cd /path/to/project/
# 选择 Python 版本
pyenv local 3.6.7
pip show pipenv > /dev/null
if [ $? -ne 0 ]; then
# 安装 pipenv
pip install pipenv
# 创建虚拟环境,安装依赖
pipenv install
fi
# 运行脚本
pipenv run python main.py