最近一段时间在使用数据库时需要把文件存入数据库中,第一次经历存文件到数据库,各种上网找资料,还好搞定,分享一下,也让自己做个记录。
mysql版本:
[root@localhost mysql]# mysql --version
mysql Ver 15.1 Distrib 5.5.68-MariaDB, for Linux(x86_64) using readline 5.1
首先介绍一下参数:secure_file_priv
这个参数用来限制数据导入和导出操作的效果,例如执行LOAD DATA、SELECT … INTO OUTFILE语句和LOAD_FILE()函数。这些操作需要用户具有FILE权限。
当secure_file_priv的值为null ,表示限制mysqld 不允许导入|导出;
当secure_file_priv的值为/指定路径时/ ,表示限制mysqld 的导入|导出只能发生在/指定路径时/目录下;
当secure_file_priv的值没有具体值时,表示不对mysqld 的导入|导出做限制;
查看当前环境参数配置:
MySQL [(none)]> show variables like"secure_file_priv";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | NULL |
+------------------+-------+
1 row in set(0.00 sec)
MySQL [(none)]>
此时secure_file_priv未做配置,不允许导入导出,在"/etc/my.cnf"文件中[mysqld]节中修改或增加配置“secure_file_priv=”,保存后重启mysql服务。
[mysqld]
secure_file_priv=
log_slave_updates=1
slow_query_log=1
general_log=0
pid-file=/usr/local/mysql/mysql.pid
user=mysql
...
再次查看配置参数:
MySQL [(none)]> show variables like"secure_file_priv";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | |
+------------------+-------+
1 row in set(0.00 sec)
MySQL [(none)]>
此时已经不对导入导出做限制。
验证是否可以将文件保存到数据库,再导出保存的文件:
创建一个测试表test_file:
MySQL [(none)]> create table if not exists test_file(filePathvarchar(200) primary key, fileInfo blob);
该表有两个字段,分别是filePath:文件存储的绝对路径,并设为主键,fileInfo:文件内容(注:blob类型为大文件存储类型,最大限制到65K)
MySQL [jacob]> show tables;
+-----------------+
| Tables_in_jacob |
+-----------------+
| test_file |
+-----------------+
1 row in set(0.00 sec)
MySQL [jacob]> desc test_file;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| filePath |varchar(200) | NO | PRI | NULL | |
| fileInfo | blob | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+
2 rows in set(0.00 sec)
MySQL [jacob]>
创建测试文件:
[root@localhost tmp]# pwd
/home/yourname/mysql/tmp
[root@localhost tmp]# md5sum test_file
4fa502de692709d1cf5eea47f05936cd test_file
[root@localhost tmp]# cat test_file
HHHHHHHHHHHHHHHHHHHH
eeeeeeeeeeeeeeeeeeee
llllllllllllllllllll
llllllllllllllllllll
oooooooooooooooooooo
[root@localhost tmp]#
将该文件用sql语句保存到mysql中的test_file表中:
MySQL [jacob]> replace into test_file values("/home/yourname/mysql/tmp/test_file", LOAD_FILE("/home/yourname/mysql/tmp/test_file"));
Query OK, 1 row affected(0.02 sec)
MySQL [jacob]>
检查是否保存成功:
MySQL [jacob]> select *from test_file;
+---------------------------------------+-----------------------------------------------------------------------------------------------------------+
| filePath | fileInfo |
+---------------------------------------+-----------------------------------------------------------------------------------------------------------+
| /home/yourname/mysql/tmp/test_file | HHHHHHHHHHHHHHHHHHHH
eeeeeeeeeeeeeeeeeeee
llllllllllllllllllll
llllllllllllllllllll
oooooooooooooooooooo
|
+---------------------------------------+-----------------------------------------------------------------------------------------------------------+
1 row in set(0.00 sec)
MySQL [jacob]>
此刻已经完成将测试文件写入测试表中。
下来就是把保存的文件读出来,直接上sql语句:
MySQL [(none)]> select fileInfo from test_file where filePath="/home/yourname/mysql/tmp/test_file" into dumpfile"/var/lib/mysql/test_file_1";
检查执行结果
[root@localhost mysql]# ll *执行前检查,没有test_file_1文件*
total 0
[root@localhost mysql]# ll *执行后检查,有test_file_1文件*
total 4
-rw-rw-rw- 1 mysql mysql 105 Feb 24 10:44 test_file_1
[root@localhost mysql]# md5sum test_file_1
4fa502de692709d1cf5eea47f05936cd test_file_1
[root@localhost mysql]# cat test_file_1
HHHHHHHHHHHHHHHHHHHH
eeeeeeeeeeeeeeeeeeee
llllllllllllllllllll
llllllllllllllllllll
oooooooooooooooooooo
[root@localhost mysql]#
经过对比文件内容以及md5值,写入mysql前和mysql后文件内容没有改变,实现将文件写入mysql数据库以及从mysql数据库读出;
注意:
select fileInfo from test_file where filePath="/home/yourname/mysql/tmp/test_file" into dumpfile"/var/lib/mysql/test_file_1";
这句“/var/lib/mysql/”中的路径是mysql路径,有些版本在默认情况下是强制限制MySQL导出文件到除了MySQL的数据库文件(datadir)之外的其他路径,test_file_1是要保存的文件名。
附脚本实现,输入参数为文件绝对路径,输出文件路径为输入时的路径,即按原文件的路径写出,忽略脚本中的HA判断:
写入mysql中:
[root@localhost mysql]# cat writeMysql.sh#!/bin/bash -MY_CNF="/etc/my.cnf"HA_STATUS=/usr/lib/eGW/.ha.statusMYSQL_TABLE="crt_table"functionmysql_write(){echo"**********Execute write mysql function**********">> /var/log/messageslocalha_status=$(cat $HA_STATUS)echo"The server status:$ha_status">> /var/log/messagesif[[$ha_status=="BACKUP"]];thenecho"*************End write mysql function*************">> /var/log/messagesexit1;filine=`cat ${MY_CNF}|grep -n"secure_file_priv"|grep -v"\#"|awk -F:'{print$1}'|sed -n 1p`if["X${line}"!="X"];thensed -i"${line}c secure_file_priv="$MY_CNFif[$? -eq0];thenecho"$LINENO: set secure_file_priv= successfully">> /var/log/messageselseecho"$LINENO: set secure_file_priv= failed">> /var/log/messagesexitfielseecho"Append modify">> /var/log/messagessed -i'/\[mysqld\]/a\'secure_file_priv=''$MY_CNFif[$? -eq0];thenecho"set secure_file_priv= successfully">> /var/log/messageselseecho"set secure_file_priv= failed">> /var/log/messagesexitfifiecho$1>> /var/log/messagesif[[ -f"$1"]];thenlocalfile_path=$1echo"$LINENO:$file_path">> /var/log/messagesmysql="mysql -uroot -pbaiOMC@123"sql="use radius;create table if not exists$MYSQL_TABLE(filePath varchar(200) primary key, fileInfo blob);replace into$MYSQL_TABLE values (\"$file_path\", LOAD_FILE(\"$file_path\"));"echo"$mysql -e\"$sql\"">> /var/log/messages$mysql -e"$sql"elseecho"This file:$1, not exist">> /var/log/messagesfiecho"*************End write mysql function*************">> /var/log/messages}
mysql_write$1
从mysql中读出:
[root@localhost mysql]# cat readMysql.sh#! /bin/bash -MYSQL_TABLE="crt_table"functionread_mysql(){echo"**********Execute read mysql function**********">> /var/log/messages#有些版本在默认情况下是强制限制MySQL导出文件到除了MySQL的数据库文件(datadir)之外的其他路径mysqlPath=/var/lib/mysql/my_sql="mysql -uroot -pbaiOMC@123 -s radius"sql_num="select count(filePath) from$MYSQL_TABLE;"sql_path="select filePath from$MYSQL_TABLE"num=$($my_sql -e"$sql_num")echo"There are$num records in the table">> /var/log/messagespath=$($my_sql -e"$sql_path")for((i=0; i<$num; i++))dob=$(expr $i +1)
arrA[$i]=`echo $path|awk -vvalue=${b} -F" "'{print$value}'`echo${arrA[$i]}>> /var/log/messagesfile_name=`echo ${arrA[$i]##*/}`echo"save file:$file_name">> /var/log/messagessql_write="select fileInfo from$MYSQL_TABLE where filePath=\"${arrA[$i]}\" into dumpfile\"${mysqlPath}$file_name\";"$my_sql -e"${sql_write}"save_path=`echo ${arrA[$i]%/*}`echo"The file will be store:$save_path/$file_name">> /var/log/messagesmv -f${mysqlPath}$file_name$save_path/$file_namedoneecho"***********End read mysql function***********">> /var/log/messages}
read_mysql
转载请指明出处