shell下执行mysql查询导出到文件,简单高效

最近在做mysql多表查询生成报表之类的事情,表数据又比较大,大到一个表有几千万行两三个G大,小到几百万行一两个G,而且还要联合查询,又是group,又是子查询,索引都用不上,这样查几个小时不一定出来结果。 无意中试了下shell中执行sql并且导出到文件,平时在Navicat这种图形客户端半天都没结果的sql,在shell小到几分钟,大到个把小时,都不会等太久,而且导出的文件可以直接以TXT导入到数据库或者全部复制,粘贴到Excel中。 刚开始想着进入mysql-client执行查询然后导出到文件,结果失败了,提示没有权限创建文件,提供的导出文件路径只能在mysql安装目录下,其他位置没有权限新建文件,后来了解到用 echo + 管道符就好了,这种方法在root下面执行,不存在权限问题。 导出为TXT 用法: echo "sql语句" | mysql -h* -P* -u* -p 数据库 > /任意位置/xxx.txt 导出为Excel 用法: mysql -h* -P* -u* -p* 数据库 -Bse "set names utf8; select name,email from test" | sed 's/\t/","/g;s/^/"/;s/$/"/;s/\n//g' > /任意位置/xxx.csv 这样虽然方便,但是sql很长的时候就不那么方便了,写到shell里面再合适不过了,完整的shell示例如下: 随便建个shell文件吧,比如 export.sh #!/bin/bash MYSQL=/usr/bin/mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_USER=root DB_PASSWORD=root DB_DATABASE=test #OUT_FILE=/www/test.txt OUT_FILE=/www/test.csv SQL="select * from mysql" # 导出为txt #echo ${SQL} | ${MYSQL} -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD} ${DB_DATABASE} > ${OUT_FILE} # 导出为csv ${MYSQL} -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD} ${DB_DATABASE} -Bse "set names utf8; ${SQL}" | sed 's/\t/","/g;s/^/"/;s/$/"/;s/\n//g' > ${OUT_FILE} 给sh文件执行权限

Nginx反向代理远程MySQL

背景 情况是这样的,我们一个项目的客户是AWS的RDS,因为业务需要,我们要连接客户的RDS,但是客户那边只能添加一台我们机器的IP白名单。 所以我们在AWS这台RDS的同区域买了一台EC2云服务器,然后提供公网IP,这样RDS那边就添加了我们的IP白名单,可以在这台EC2上面连接那台RDS了。。。 但是ubuntu命令行操作数据库始终不太方便啊,比如:查询结果导出为Excel,导出来的文件表头是没有问题,每一条数据也都按行区分,但是多列合并放到第一列里面了,这样数据就没发操作和查看了。。。 所以打算用nginx的反向代理试一下。 准备工作 使用的是nginx的stream模块,测试前需要查看nginx是否在编译时开启了stream模块: nginx -m 如果看到 ngx_stream_module 字样就是已经编译了stream模块(我用的是Tengine)。 反向代理配置 编辑nginx配置文件: vim /etc/nginx/conf/nginx.conf 注意 stream 位于配置文件顶层,和 http 同级。 # nginx 代理 stream { # 设置代理超时时间,设的大一些,避免长连接因为超时时间而中断 proxy_timeout 3d; server { listen 3307; listen [::]:3307; proxy_pass xxx.com:3306; } } 重启nginx # 使修改后的配置文件生效 nginx -c /etc/nginx/conf/nginx.conf # 平滑重启nginx nginx -s reload 测试 客户端连接你的反代机器IP:3307,实际上相当于连接到了xxx.com:3306这个数据库。 如果使用了云服务器,注意在策略组放行 tcp 3307端口。

MySQL每日分表定时备份shell

最近有个需求:项目是21G的mysql数据库,需要做每日备份归档,本来考虑做增量备份的,从时间安排考虑,还是先做个每日全量备份吧。 思路是先连接数据库,切换到要备份的库,然后取出所有表名,接下来遍历每张表,挨个导出为 .sql 文件,放到日期为命名的文件夹里,最后压缩为 .tar.gz 压缩包。 使用的是crontab做每日定时任务。 #!/bin/sh # 临时备份路径(未压缩的文件) OUT_DIR=/www/backup/tmp # 压缩后的备份存放路径 TAR_DIR=/www/backup/data # 数据库信息 URL=127.0.0.1 PORT=3306 USERNAME=root PASSWORD=root DBNAME=your_dbname # 当前系统时间 DATE=`date +%Y-%m-%d` # 指定命令所用的全路径 MYSQL=/usr/bin/mysql MYSQLDUMP=/usr/bin/mysqldump MYSQLADMIN=/usr/bin/mysqladmin # 日志文件 logfile=/www/backup/data.txt [ -d ${OUT_DIR} ] || mkdir -p ${OUT_DIR} [ -d ${TAR_DIR} ] || mkdir -p ${TAR_DIR} # 最终保存的数据库备份文件 TAR_BAK="your_dbname_$DATE.tar.gz" cd ${OUT_DIR} rm -rf ${OUT_DIR}/* echo "${DBNAME} backup start - ${DATE}\n" >>${logfile} # ${MYSQL} -h $URL:$PORT -u $USERNAME -p $PASSWORD -d $DBNAME -o $OUT_DIR/`$DATE +%Y-%m-%d` TABLE=$(${MYSQL} -h${URL} -P${PORT} -u${USERNAME} -p${PASSWORD} -e "use ${DBNAME};show tables;"|sed '1d') #依次列出需要备份的表的名字 for tname in ${TABLE} do #echo "${DBNAME}_${tname}_${DATE}" # 创建备份表的目录 [ -d ${OUT_DIR}/${DATE} ] || mkdir ${OUT_DIR}/${DATE} ${MYSQLDUMP} --set-gtid-purged=off --single-transaction --column-statistics=0 --default-character-set=utf8 --compress-output=LZ4 --default-parallekism=3 -h${URL} -P${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} ${tname} >${OUT_DIR}/${DATE}/${tname}.

访问 Nginx 二级目录中的 Laravel 项目

这个问题折腾了挺久时间都没成功,尝试了定义root path,也尝试了proxy_pass都不行。直到看到一篇文章,介绍的是目录伪静态转发才搞定…… 根目录为 /,laravel项目放在 aaa 下,目的是需要通过局域网IP访问laravel项目,如果不做转发,可以访问首页,但是子页面无法访问,因为没有配置rewrite。 以下是转发代码: location /aaa/public/ { if (!-e $request_filename){ rewrite ^/aaa/public/(.*)$ /aaa/public/index.php?s=$1 last; } } 参考:linux 下 nginx 二级目录中访问Laravel项目

ubuntu 安装 tengine 和 php-fpm 运行php脚本

Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。 从2011年12月开始,Tengine成为一个开源项目,Tengine团队在积极地开发和维护着它。Tengine团队的核心成员来自于淘宝、搜狗等互联网企业。Tengine是社区合作的成果,我们欢迎大家参与其中,贡献自己的力量。 Tengine完全兼容Nginx,因此可以参照Nginx的方式来配置Tengine。 Tengine官方下载地址:http://tengine.taobao.org/download_cn.html 目前最新版本为 tengine-2.3.2。 tengine 编译安装 wget http://tengine.taobao.org/download/tengine-2.3.2.tar.gz tar -zxvf tengine-2.3.2.tar.gz cd tengine-2.3.2 apt update # 安装gcc编译器 make,众多依赖包 apt install -y gcc g++ make libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev # --sbin 指定 tengine 的安装位置为 /usr/sbin/nginx,这样就可以直接指向 nginx [xxx] 指令 ./configure --prefix=/etc/nginx/ --sbin-path=/usr/sbin/nginx --with-stream && make && make install # 安装完成后查看 tengine 版本 nginx -v 安装php 如果你的服务器没有php7.4,比如apt仓库只到php7.2,那么添加这个源(必须以root运行)参考链接 sudo add-apt-repository ppa:ondrej/php 安装php7.4 apt install -y php7.4-fpm # 安装完成之后查看php版本 php -v # 查看php已安装的扩展 php -m 到这里还没结束,还要对 nginx(tengine) 和 php 进行配置,才能运行php脚本。

html svg转换成canvas,生成图片base64地址

今天做小程序时发现小程序不支持svg标签,网页上的图标是 html5 的 svg 标签,没有字体源文件,通过 search 看到有人给出了解决方案,这里整理一下,方便自己或者有需要的朋友开箱即用。 这里用到了 canvg.js 这个goole发布的插件,原理是把 svg 转成canvas,再利用canvas的toDataURL,输出图片的base64地址。 canva.js 需要依赖于rgbcolor.js。这个应该都比较容易下载到。 附上下载地址:https://github.com/canvg/canvg 下面是demo: <!DOCTYPE html> <head> <meta charset="UTF-8"> <title>html svg转换成canvas,生成图片base64地址</title> <!--[if IE]> <script type="text/javascript" src="flashcanvas.js"></script> <![endif]--> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/canvg/1.4/rgbcolor.min.js"></script> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/canvg/dist/browser/canvg.min.js"></script> <script type="text/javascript"> var context; var redraw = false; function resize() { var c = document.getElementById('container'), custom = true; if (!custom) { c.style.width = (window.innerWidth || document.body.clientWidth) + 'px'; c.style.height = (window.innerHeight || document.body.clientHeight) + 'px'; } else { c.

使用php生成RSA公钥私钥及进行加密/解密/签名/验证

这篇文章主要介绍使用PHP开发接口,数据实现RSA加密解密后使用,实例分析了PHP自定义RSA类实现加密与解密的技巧,非常具有实用价值,需要的朋友可以参考下。 简单介绍RSA: RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。但是有不少新手对它不太了解。下面仅作简要介绍。RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名。RSA以它的三个发明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名,这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法。RSA的安全基于大数分解的难度。其公钥和私钥是一对大素数(100到200位十进制数或更大)的函数。从一个公钥和密文恢复出明文的难度,等价于分解两个大素数之积(这是公认的数学难题)。 下面为具体类:Rsa.class.php <?php /** * RSA算法类 * 签名及密文编码:base64字符串/十六进制字符串/二进制字符串流 * 填充方式: PKCS1Padding(加解密)/NOPadding(解密) * * Notice:Only accepts a single block. Block size is equal to the RSA key size! * 如密钥长度为1024 bit,则加密时数据需小于128字节,加上PKCS1Padding本身的11字节信息,所以明文需小于117字节 */ class RSA { private $pubKey = null; private $priKey = null; /** * 构造函数 */ public function __construct() { // 需要开启openssl扩展 if (!extension_loaded("openssl")) { $this->_error("Please open the openssl extension first."); } } /** * 读取公钥和私钥 * @param string $public_key_file 公钥文件(验签和加密时传入) * @param string $private_key_file 私钥文件(签名和解密时传入) */ public function init($public_key_file = '', $private_key_file = '') { if ($public_key_file) { $this->_getPublicKey($public_key_file); } if ($private_key_file) { $this->_getPrivateKey($private_key_file); } } /** * 自定义错误处理 */ private function _error($msg) { die('RSA Error:' .

jquery的serialize()不提交未选中的checkbox的问题

jquery的$(form).serialize()不会提交未选中的checkbox,解决方法是未选中时向页面插入一个同name的隐藏input。 $('input[type="checkbox"]').on("click", function () { var name = $(this).attr("name"); if ($(this).checked) { $(this).val(1); $(this).parent().find('input[type="hidden"][name="' + name + '"]').remove(); } else { $(this).val(0); $(this).parent().append('<input type="hidden" name="' + name + '" value="0">'); } }); 经过此方法设置后,checkbox序列被完整提交,原本被用户选定的checkbox的value为1,未被选定的value为0。

进程、线程与协程的比较

进程、线程和协程是三个在多任务处理中常听到的概念,三者各有区别又相互联系。 进程 进程是一个程序在一个数据集中的一次动态执行过程,可以简单理解为“正在执行的程序”,它是CPU资源分配和调度的独立单位。 进程一般由程序、数据集、进程控制块三部分组成。我们编写的程序用来描述进程要完成哪些功能以及如何完成;数据集则是程序在执行过程中所需要使用的资源;进程控制块用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系统感知进程存在的唯一标志。 进程的局限是创建、撤销和切换的开销比较大。 线程 线程是在进程之后发展出来的概念。 线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行过程中的最小单元,由线程ID、程序计数器、寄存器集合和堆栈共同组成。一个进程可以包含多个线程。 线程的优点是减小了程序并发执行时的开销,提高了操作系统的并发性能,缺点是线程没有自己的系统资源,只拥有在运行时必不可少的资源,但同一进程的各线程可以共享进程所拥有的系统资源,如果把进程比作一个车间,那么线程就好比是车间里面的工人。不过对于某些独占性资源存在锁机制,处理不当可能会产生“死锁”。 协程 协程是一种用户态的轻量级线程,又称微线程,英文名Coroutine,协程的调度完全由用户控制。人们通常将协程和子程序(函数)比较着理解。 子程序调用总是一个入口,一次返回,一旦退出即完成了子程序的执行。 协程的起始处是第一个入口点,在协程里,返回点之后是接下来的入口点。在python中,协程可以通过yield来调用其它协程。通过yield方式转移执行权的协程之间不是调用者与被调用者的关系,而是彼此对称、平等的,通过相互协作共同完成任务。其运行的大致流程如下: 第一步,协程A开始执行。 第二步,协程A执行到一半,进入暂停,通过yield命令将执行权转移到协程B。 第三步,(一段时间后)协程B交还执行权。 第四步,协程A恢复执行。 协程的特点在于是一个线程执行,与多线程相比,其优势体现在: 协程的执行效率非常高。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。 协程不需要多线程的锁机制。在协程中控制共享资源不加锁,只需要判断状态就好了。 Tips: 利用多核CPU最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。 Refer:https://blog.csdn.net/blateyang/article/details/78088851

MySql按中文(汉字)拼音首字母检索

实现按拼音首字母检索一种是直接增加字段存储名称首字母,但是这样会使表都一个字段,每次录入都要转换 这是通常的做法,另一种是接下来介绍的这种,按照汉字编码排序来实现的,无需给表多增字段。 首先我们有一个这样的数组: array( 'A'=>'吖', 'B'=>'八', 'C'=>'嚓', 'D'=>'咑', 'E'=>'妸', 'F'=>'发', 'G'=>'旮', 'H'=>'铪', 'J'=>'丌', 'K'=>'咔', 'L'=>'垃', 'M'=>'嘸', 'N'=>'拏', 'O'=>'噢', 'P'=>'妑', 'Q'=>'七', 'R'=>'呥', 'S'=>'仨', 'T'=>'他', 'W'=>'屲', 'X'=>'夕', 'Y'=>'丫', 'Z'=>'帀' ); 查出姓名拼音首字母是a的 SELECT * FROMtbl WHERE CONVERT( name USING gbk ) COLLATE gbk_chinese_ci >='吖' AND CONVERT( name USING gbk ) COLLATE gbk_chinese_ci < '八' 查出姓名拼音首字母是b的 SELECT * FROMtbl WHERE CONVERT( name USING gbk ) COLLATE gbk_chinese_ci >='八' AND CONVERT( name USING gbk ) COLLATE gbk_chinese_ci < '嚓' …