最近在有个需求 就是定时查询数据库,有三个方案,
1.java定时任务
2.数据库定时器,定时执行存储过程
3.shell脚本调用存储过程,crontab定时执行shell脚本
我使用的是第三种方法,这一篇主要数一下我踩过的坑!!!
shell脚本,调用存储过程:
mysql -h *** -u *** -D *** -p*** -e ***
-h ip地址
-u 数据库用户
-D 数据库
-p密码
-e 调用存储过程的语句 call haha()
-p和密码之间没有空格,请注意!
shell脚本范例:
#ip地址
HOST="xxx"
#端口号
PORT="xxx"
#用户名
USER="xxx"
#密码
PASSWORD="xxx"
#数据库名
DATABASE="xxx"
#路径,日志所在路径,
DIR="xxx"
#日志
log="log.txt"
#存储过程
CALL="call m_user_day()"
#当前时间
cur_dateTime="`date +%Y-%m-%d,%H:%m:%s`"
MAILTO=""
cd ${DIR}
#输入到日志
SQL="exec mysql -h${HOST} -u${USER} -p${PASSWORD} -D ${DATABASE} --default-character-set=utf8 -e \"${CALL}\""
echo ${SQL} >> ${log} 2>&1
echo ${cur_dateTime} >> ${log} 2>&1
if mysql -h ${HOST} \
-u ${USER} \
-p${PASSWORD} \
-D ${DATABASE} \
--default-character-set=utf8 \
-e "${CALL}"; then
echo "ok" >> ${log} 2>&1
else
echo "error" >> ${log} 2>&1
fi
exit
shell编写后,肯定要先测试一下shell脚本是否可以:
一.MAILTO="",禁止发送邮件,定时器执行shell脚本时,会以发送邮件的形式表现,使shell脚本的echo无作用
所以必须禁止发送邮件,
二.如果在shell脚本中需要进行输出的话,echo并不会起作用,只能将语句输出到一个日志文件中,
需要 >> 重定向到一个文件中,并在后面加上2>&1 如echo "ok" >> ${log} 2>&1
需要 MAILTO="" >> 2>&1 三者配合才可以将日志输出到文件中
三.如果脚本语句没有问题的话,进行执行脚本,脚本执行时,如果超过10秒,那你对数据库的操作就是失败的了,
最有可能报的一个错误就是 连接不到数据库,这是一个很笼统的错误,错误原因很多
1.网络原因,
ping www.baidu.com 没有问题
ping 数据库所在的服务器ip 不通,就是网络的问题了,
我就是这样的问题,(云服务器上执行脚本,操作公司内网服务器上的数据库),执行脚本时,一直提示mysql连接失败
所以,先ping ip,看看是否可以连通,如果不可以,就要注意一下了
2.ping ip可以的话,在执行shell脚本,还是提示mysql连接失败,就有可能是mysql的问题了
有可能是mysql没有开启远程调用权限
解决办法:1.关闭mysql,在my.ini文件的最后一行加上一句话 skip-grant-tables 开启mysql
2.更新user表的Host为% update user authentication_String
UPDATE user SET authentication_String=PASSWORD(’newpassword’) where USER=’root’;
注意,mysql的password列有可能变为了authentication_String
FLUSH PRIVILEGES重启misql
登陆mysql
之后就ok了