MySQL slow query log consists of SQL statements that took more than long_query_time seconds to complete execution & required atleast min_examined_row_limit to be examined. By default, administrative queries & those that don’t use indexes for lookups are not logged.

Two common techniques used by Logrotate are:

copytruncate: Instead of moving the old log file & optionally creating a new one, logrotate truncates the original log file in place after creating a copy.
nocopytruncate: Do not truncate the original log file in place after creating a copy.
Truncating log files can block MySQL because the OS serializes access to the inode during the truncate operation. Therefore, it is recommended to temporarily stop slow query logging, flush slow logs, rename the old log file & finally re-enable slow query logging.

Flushing logs might take a considerable amount of time, so, to avoid filling slow log buffer, it’s advisable to temporarily disable MySQL slow query logging & re-enabling it once the rotation is complete.

Manual Rotation
To manually rotate slow query logs, we’ll temporarily disable slow query logging, flush slow logs, rename the original file & finally re-enable slow query logging.

get the path to slow query log file

MariaDB [(none)]> show variables like '%slow_query%';
+---------------------+-------------------------------+
| Variable_name | Value |
+---------------------+-------------------------------+
| slow_query_log | ON |
| slow_query_log_file | /var/lib/mysql/mysql-slow.log |
+---------------------+-------------------------------+
2 rows in set (0.00 sec)
temporarily disable slow query logging

MariaDB [(none)]> set global slow_query_log=off;
Query OK, 0 rows affected (0.00 sec)
flush only slow logs

MariaDB [(none)]> flush slow logs;
Query OK, 0 rows affected (0.00 sec)
rename the old log file and or compress it

[email protected]:~# mv /var/lib/mysql/mysql-slow.log /var/lib/mysql/mysql-slow-$(date +%Y-%m-%d).log
[email protected]:~# gzip -c /var/lib/mysql/mysql-slow-$(date +%Y-%m-%d).log > /var/lib/mysql/mysql-slow-$(date +%Y-%m-%d).log.gz
finally, re-enable slow query logging

MariaDB [(none)]> set global slow_query_log=on;
Query OK, 0 rows affected (0.00 sec)

使用 logrotate

使用 logrotate 您可以安全的对 mysql query log 的日志进行切分
logrotate: /etc/logrotate.d/mysql-query

/var/lib/mysql/ubuntu.log {
        daily
        size 1G
        rotate 2
        missingok
        create 640 mysql adm
        compress
        sharedscripts
        postrotate
                test -x /usr/bin/mysqladmin || exit 0
                # If this fails, check debian.conf! 
                MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf"
                if [ -z "`$MYADMIN ping 2>/dev/null`" ]; then
                  # Really no mysqld or rather a missing debian-sys-maint user?
                  # If this occurs and is not a error please report a bug.
                  #if ps cax | grep -q mysqld; then
                  if killall -q -s0 -umysql mysqld; then
                    exit 1
                  fi
                else
                  $MYADMIN flush-logs
                fi
        endscript
}

参数                         功能
   compress                     通过gzip 压缩转储以后的日志
   nocompress                   不需要压缩时,用这个参数
   copytruncate                 用于还在打开中的日志文件,把当前日志备份并截断
   nocopytruncate               备份日志文件但是不截断
   create mode owner group      转储文件,使用指定的文件模式创建新的日志文件
   nocreate                     不建立新的日志文件
   delaycompress 和 compress    一起使用时,转储的日志文件到下一次转储时才压缩
   nodelaycompress              覆盖 delaycompress 选项,转储同时压缩。
   errors address               专储时的错误信息发送到指定的Email 地址
   ifempty                      即使是空文件也转储,这个是 logrotate 的缺省选项。
   notifempty                   如果是空文件的话,不转储
   mail address                 把转储的日志文件发送到指定的E-mail 地址
   nomail                       转储时不发送日志文件
   olddir directory             转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
   noolddir                     转储后的日志文件和当前日志文件放在同一个目录下
   prerotate/endscript          在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行
   postrotate/endscript         在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行
   daily                        指定转储周期为每天
   weekly                       指定转储周期为每周
   monthly                      指定转储周期为每月
   rotate count                 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份
   tabootext [+] list           让logrotate 不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig, .rpmsave, v, 和 ~
   size 1G                    当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB (sizek)或者MB (sizem).

dateext: archive old log files by adding a date extension using the format YYYYMMDD instead of using a number.
missingok: if a log file is missing, don’t issue an error message
rotate 20: 保存多少个切分文件
notifempty: don’t rotate empty log files
sharedscripts: run prerotate & postrotate scripts only once, no matter how many logs match the wildcard pattern

网址规范化一直是困扰站长以及搜索引擎的一个问题。据估计,网上有10%-30%的URL是内容相同但URL不一样的不规范化网址。

这就造成几个问题。比如:

对站长来说,多个URL存在分散了页面权重,不利于排名。
对搜索引擎来说,浪费资源,浪费带宽。
搜索引擎发现多个网址内容相同时,不会惩罚,而会尽可能找出那个应该是规范化的网址。但程序毕竟只是程序,可能出错,挑出来的可能不是站长想要的那个规范化网址。
网站上网址规范化问题太严重的话,也可能影响收录。一个权重不很高的域名,能收录的总页面数字是有限的。搜索引擎把资源花在收录不规范的网址上,留下给真正不同内容的资源就减少了。

要解决URL规范化问题也有很多选项,比如:

在Google管理员工具中设置带3W和不带3W的,哪一个是规范化版本
使用301转向,把不规范化URL全部转向到规范化URL
确保使用的CMS系统只产生规范化网址
确保网站上所有站内链接都指向规范化网址
在提交给搜索引擎的网站地图中全部指定规范化网址

但这些方法都各有局限。

Google管理员工具不适用于其他搜索引擎
有的站长因为某种原因做不了301转向
CMS系统大部分情况下不受自己控制
内部链接自己可以控制,但其他人链接到自己网站上就不受控制了

总之,虽然有解决方法备选,但网址规范化到目前为止还是个不小的问题。

前几天Google,雅虎,微软共同发布了一个新的标签canonical tag,用于解决网址规范化问题。

简单说,就是在HTML文件的头部加上这样一段代码:

<link rel=”canonical” href=”http://www.example.com/product.php?item=swedish-fish” />

意义就是这个网页的规范化网址应该是:

http://www.example.com/product.php?item=swedish-fish

下面这些URL都可以加上这段代码:

http://www.example.com/product.php?item=swedish-fish&category=gummy-candy

http://www.example.com/product.php?item=swedish-fish&trackingid=1234&sessionid=5678

这些URL的真正规范化网址就都成为:

http://www.example.com/product.php?item=swedish-fish

简单说,这个标签相当是一个页面内的301转向。区别在于用户并不被转向,还是停留在不变网址上,而搜索引擎会把它当作是301转向处理,也就是说把页面链接的权重都集中到代码中指明的规范化网址上。

另外有几个细节站长需要注意:

这个标签只是一种建议或暗示,而不是指令,它不像robots文件那样是个指令。所以搜索引擎会很大程度上考虑这个代码,但并不是百分之百,还会考虑其他情况来判断规范化网址。这也防止站长有可能把网址弄错。
这段代码既可以使用绝对地址,也可以使用相对地址。通常还是建议使用绝对地址比较保险。
指定的规范化网址上的内容,与其他使用这段代码的非规范化网址内容可以有一些不同,不一定完全一样。比如在电子商务网站上有很多按价钱、颜色,、尺寸升降排序,生成的URL全都不一样,但内容大体相同,只有细小区别,就可以使用这个标签。
指定的规范化网址可以是不存在页面,返回404,也可以是还没有被收录的页面。但是不建议这么做,别没事找事。
这个标签适用于同一个域名内,包括二级域名。但不适用于不同域名之间,防止有人劫持。
别把这个标签当救命草,首先还是得把网站结构做好,尽量避免出现URL规范化问题。这只是最后万不得已的方法。

敏感的人大概能从这个新标准里看到建立大量外部链接的机会。

最后提一句,这个标准被3大搜索引擎Google,雅虎,微软同时支持。

遵循良好的编码风格,可以有效的提高代码的可读性,降低出错几率和维护难度。在团队开发中,使用(尽量)统一的编码风格,还可以降低沟通成本。

网上有很多版本的编码规范,基本上都是遵循 PEP8 的规范:

PEP 0008 – Style Guide for Python Code
Google 的 Python 风格指南
Python Guide - Code Style
Pocoo Styleguide

不要使用 tab 缩进
使用任何编辑器写 Python,请把一个 tab 展开为 4 个空格
绝对不要混用 tab 和空格,否则容易出现 IndentationError

命名

使用有意义的,英文单词或词组,绝对不要使用汉语拼音
package/module 名中不要出现 -

import

  • 所有 import 尽量放在文件开头,在 docstring 下面,其他变量定义的上面
  • 不要使用 from foo imort *
  • import 需要分组,每组之间一个空行,每个分组内的顺序尽量采用字典序,分组顺序是:
    • 标准库
    • 第三方库
    • 本项目的 package 和 module
    • 不要使用隐式的相对导入(implicit relative imports),可是使用显示的相对导入(explicit relative imports),如 from ..utils import validator,最好使用全路径导入(absolute imports)
  • 对于不同的 package,一个 import 单独一行,同一个 package/module 下的内容可以写一起:
  • 为了避免可能出现的命名冲突,可以使用 as 或导入上一级命名空间
  • 不要出现循环导入(cyclic import)

注释

  • 文档字符串 docstring, 是 package, module, class, method, function 级别的注释,可以通过 doc 成员访问到,注释内容在一对 """ 符号之间
  • function, method 的文档字符串应当描述其功能、输入参数、返回值,如果有复杂的算法和实现,也需要写清楚
  • 不要写错误的注释,不要无谓的注释
  • 优先使用英文写注释,英文不好全部写中文,否则更加看不懂

异常

  • 不要轻易使用 try/except
  • except 后面需要指定捕捉的异常,裸露的 except 会捕捉所有异常,意味着会隐藏潜在的问题
  • 可以有多个 except 语句,捕捉多种异常,分别做异常处理
  • 使用 finally 子句来处理一些收尾操作
  • try/except 里的内容不要太多,只在可能抛出异常的地方使用,如:
  • 从 Exception 而不是 BaseException 继承自定义的异常类

Class(类)

  • 显示的写明父类,如果不是继承自别的类,就继承自 object 类
  • 使用 super 调用父类的方法
  • 支持多继承,即同时有多个父类,建议使用 Mixin

字符串

  • 使用字符串的 join 方法拼接字符串
  • 使用字符串类型的方法,而不是 string 模块的方法
  • 使用 startswith 和 endswith 方法比较前缀和后缀
  • 使用 format 方法格式化字符串

比较

  • 空的 list, str, tuple, set, dict 和 0, 0.0, None 都是 False
  • 使用 if some_list 而不是 if len(some_list) 判断某个 list 是否为空,其他类型同理
  • 使用 is 和 is not 与单例(如 None)进行比较,而不是用 == 和 !=
  • 使用 if a is not None 而不是 if not a is None
  • 用 isinstance 而不是 type 判断类型
  • 不要用 == 和 != 与 True 和 False 比较(除非有特殊情况,如在 sqlalchemy 中可能用到)
  • 使用 in 操作:
# bad
if d.has_key(k):
    do_something()

# good
if k in d:
    do_something()
  • 用 set 加速 “存在性” 检查,list 的查找是线性的,复杂度 O(n),set 底层是 hash table, 复杂度 O(1),但用 set 需要比 list 更多内存空间

其他

  • 使用列表表达式(list comprehension),字典表达式(dict comprehension, Python 2.7+) 和生成器(generator)
  • dict 的 get 方法可以指定默认值,但有些时候应该用 [] 操作,使得可以抛出 KeyError
  • 使用 for item in list 迭代 list, for index, item in enumerate(list) 迭代 list 并获取下标
  • 使用内建函数 sorted 和 list.sort 进行排序
  • 适量使用 map, reduce, filter 和 lambda,使用内建的 all, any 处理多个条件的判断
  • 使用 defaultdict (Python 2.5+), Counter(Python 2.7+) 等 “冷门” 但好用的标准库算法和数据结构
  • 使用装饰器(decorator)
  • 使用 with 语句处理上下文
  • 有些时候不要对类型做太过严格的限制,利用 Python 的鸭子类型(Duck Type)特性
  • 使用 logging 记录日志,配置好格式和级别
  • 了解 Python 的 Magic Method:A Guide to Python’s Magic Methods, Python 魔术方法指南
  • 阅读优秀的开源代码,如 Flask 框架, Requests for Humans
  • 不要重复造轮子,查看标准库、PyPi、Github、Google 等使用现有的优秀的解决方案

临时修改

  • 查看网卡信息
ifconfig

该命令会打印出所有的网卡信息, 根据打印出的信息, 找到需要设置的网卡进行设置。

  • 临时设置网卡 mtu
ifconfig eth0 mtu 9000
  • 检查效果
    使用 ifconfig eth0 命令, 根据打印出的信息, 查看修改的效果。

永久的修改

修改配置文件 /etc/network/interfaces ,增加一行, 保存退出

mtu 1280
  • 重启网络
/etc/init.d/networking restart
  • 查看效果
ifconfig eth0

相关资料

  • http://www.microhowto.info/howto/change_the_mtu_of_a_network_interface.html
  • https://www.cyberciti.biz/faq/how-can-i-setup-the-mtu-for-my-network-interface/

dpkg -l |grep ^rc|awk '{print $2}' |sudo xargs dpkg -P

这个命令, 可以将系统中的软件残留清除, 使用了一下, 删除了许多之前卸载但未卸干净的文件, 挺好, 留存。