6

I have a couple files that I want to store together in a blob type column of a mysql table. So I just put them into a folder and then zipped it. I've never had any trouble storing images, text and pdf files using the load_file() function, but when I try with the .zip folder I get back a NULL value. What am I missing? Thanks!

4
  • Yeah ok, but the question then becomes how to store multiple files into a single column of type blob of a mysql table. Any idea other than zipping the files together?
    – IDK
    Commented Feb 10, 2021 at 10:14
  • 1
    Show us the code being used to do the INSERT and tell us what application is doing the work (PHP? Java? VB? other?)
    – Rick James
    Commented Feb 10, 2021 at 21:05
  • I cannot reproduce. Due to the size I post a comment as an answer. Add your issue log to the question by the same way. Also show values for secure_file_privilege and max_allowed_packet variables, the size of the file to be loaded, and ensure that your account have FILE privilege.
    – Akina
    Commented Feb 11, 2021 at 7:12
  • how big is the zip file? Commented Feb 14, 2021 at 9:06

2 Answers 2

6
+100

I have noted the same phenomenon.

It does seem a bit strange indeed and OS related. Here is the result of my investigation (using MARIA DB 10.4, Windows 10 Pro20H2):

In a given folder, C:\zipfolder for ex., I've created a textfile zipdoc.txt with some text content and a zip file containing the textfile.

This gives the folowing load_file output:

select load_file('C:\\zipfolder\\zipdoc.txt');
+----------------------------------------+
| load_file('C:\\zipfolder\\zipdoc.txt') |
+----------------------------------------+
| zipcontent text                        |
+----------------------------------------+

select load_file('C:\\zipfolder\\zipdoc.zip');
+----------------------------------------+
| load_file('C:\\zipfolder\\zipdoc.zip') |
+----------------------------------------+
| NULL                                   |
+----------------------------------------+

Changing the file extension from .zip to .zip_ for ex. fixes the issue:

select load_file('C:\\zipfolder\\zipdoc.zip_');
+---------------------------------------------------------------------------------------------------------------------------------------+
| load_file('C:\\zipfolder\\zipdoc.zip_')                                                                                               |
+---------------------------------------------------------------------------------------------------------------------------------------+
| PK♥♦¶     FÄLR├SAÏ☼   ☼
   zipdoc.txtzipcontent textPK☺☻¶ ¶     FÄLR├SAÏ☼   ☼
       ☺         zipdoc.txtPK♣♠    ☺ ☺ 8   7      |
+---------------------------------------------------------------------------------------------------------------------------------------+

So, it looks like Windows 10 is blocking the access to .zip files in a more restrictive way than other files.

Giving EVERYONE access to the zip-file allows the load_file function accessing of the original zip-file. After granting the access with the following Powerhell script (adopted from here):

$acl = Get-Acl C:\zipfolder\zipdoc.zip
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("Jeder","Read","Allow")
$acl.SetAccessRule($AccessRule)
$acl | Set-Acl C:\zipfolder\zipdoc.zip

load_file is able to access the zipfile:

select load_file('C:\\zipfolder\\zipdoc.zip');
+---------------------------------------------------------------------------------------------------------------------------------------+
| load_file('C:\\zipfolder\\zipdoc.zip')                                                                                                |
+---------------------------------------------------------------------------------------------------------------------------------------+
| PK♥♦¶     FÄLR├SAÏ☼   ☼
   zipdoc.txtzipcontent textPK☺☻¶ ¶     FÄLR├SAÏ☼   ☼
       ☺         zipdoc.txtPK♣♠    ☺ ☺ 8   7      |
+---------------------------------------------------------------------------------------------------------------------------------------+

So, the solution is to grant EVERYONE access to the zip-files or just changing the extension of the files (It remains a task for admins to find a more restrictive working access level).

Complement: As mentioned by @Álvaro González, the use of an archiving program that sets the appropriate rights is also a solution.

4
  • Great research! The key point seems to be what tool you use to create the ZIP archive. 7-Zip sets access for the user that creates the archive but Windows Zip Folders sets it to NT AUTHORITY\SYSTEM. Commented Feb 13, 2021 at 12:56
  • @IDK The problem seems to be solved, but from my own experience I would advise against storing large amounts of file content in the database as the performance, especially of MySQL InnoDB tables, decreases significantly as the table size increases. Instead, I recommend storing the files in a file system and only storing the relative path in the database, possibly with some metadata such as size and file time. Commented Feb 14, 2021 at 15:07
  • This is strange... your @@secure_file_privilege is set to empty string and allows file operations with any folder, and at the same time the account which is used for MySQL service execution may have restricted privileges in the filesystem? This looks like incorrect/illogical MySQL and OS settings.
    – Akina
    Commented Feb 15, 2021 at 18:20
  • 1
    @Akina There is nothing special in my MySQL / OS configuration. The problematic part is the behavior of the Explorers zip functionality which sets too restrictive access level for the archives created. Files created by (all) other archivers / applications are accessible to the MySQL service, regardless of the secure_file_privilege setting. Commented Feb 15, 2021 at 20:42
3

I cannot reproduce the problem. See console output:

mysql> CREATE TABLE test (val BLOB);
Query OK, 0 rows affected (0.29 sec)

mysql> INSERT INTO test SELECT LOAD_FILE('C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\test.sql');
Query OK, 1 row affected (0.05 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> INSERT INTO test SELECT LOAD_FILE('C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\test.zip');
Query OK, 1 row affected (0.04 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT LENGTH(val) FROM test;
+-------------+
| LENGTH(val) |
+-------------+
|        5603 |
|       17725 |
+-------------+
2 rows in set (0.00 sec)

Not the answer you're looking for? Browse other questions tagged or ask your own question.