كيف يمكنني الالتفاف حول MySQL Errcode 13 مع Select Into Outfile؟

StackOverflow https://stackoverflow.com/questions/2783313

  •  03-10-2019
  •  | 
  •  

سؤال

أحاول تفريغ محتويات جدول إلى ملف CSV باستخدام MySQL SELECT في عبارة outfile. إذا فعلت:

SELECT column1, column2
INTO OUTFILE 'outfile.csv'
FIELDS TERMINATED BY ','
FROM table_name;

سيتم إنشاء Outfile.csv على الخادم في نفس الدليل يتم تخزين ملفات قاعدة البيانات هذه.

ومع ذلك ، عندما أقوم بتغيير استعلامي إلى:

SELECT column1, column2
INTO OUTFILE '/data/outfile.csv'
FIELDS TERMINATED BY ','
FROM table_name;

انا حصلت:

ERROR 1 (HY000): Can't create/write to file '/data/outfile.csv' (Errcode: 13)

Errcode 13 هو خطأ في الأذونات ، لكنني أحصل عليه حتى لو قمت بتغيير ملكية /البيانات إلى MySQL: MySQL وأعطيه 777 أذونات. يعمل MySQL كمستخدم "MySQL".

الغريب أنه يمكنني إنشاء الملف في /tmp ، ليس فقط في أي دليل آخر جربته ، حتى مع تعيين الأذونات بحيث يجب أن يكون المستخدم MySQL قادرًا على الكتابة إلى الدليل.

هذا هو MySQL 5.0.75 يعمل على Ubuntu.

هل كانت مفيدة؟

المحلول

ما هو إصدار معين من Ubuntu وهذا هو إصدار خادم Ubuntu؟

قد تكون شحنات خادم Ubuntu الأخيرة (مثل 10.04) مع Apparmor و MySQL ملف تعريف الوضع افتراضيًا. يمكنك التحقق من ذلك من خلال التنفيذ sudo aa-status مثل ذلك:

# sudo aa-status
5 profiles are loaded.
5 profiles are in enforce mode.
   /usr/lib/connman/scripts/dhclient-script
   /sbin/dhclient3
   /usr/sbin/tcpdump
   /usr/lib/NetworkManager/nm-dhcp-client.action
   /usr/sbin/mysqld
0 profiles are in complain mode.
1 processes have profiles defined.
1 processes are in enforce mode :
   /usr/sbin/mysqld (1089)
0 processes are in complain mode.

إذا تم تضمين MySQLD في وضع فرض ، فهذا هو على الأرجح ينكر الكتابة. سيتم كتابة الإدخالات أيضًا /var/log/messages عندما يمنع Apparmor كتابته/الوصول. ما يمكنك فعله هو التحرير /etc/apparmor.d/usr.sbin.mysqld و أضف /data/ و /data/* بالقرب من القاع مثل:

...  
/usr/sbin/mysqld  {  
    ...  
    /var/log/mysql/ r,  
    /var/log/mysql/* rw,  
    /var/run/mysqld/mysqld.pid w,  
    /var/run/mysqld/mysqld.sock w,  
    **/data/ r,  
    /data/* rw,**  
}

ثم اجعل Apparmor إعادة تحميل الملفات الشخصية.

# sudo /etc/init.d/apparmor reload

تحذير: سيسمح التغيير أعلاه MySQL بالقراءة والكتابة إلى دليل /البيانات. نأمل أن تكون قد فكرت بالفعل في الآثار الأمنية لهذا.

نصائح أخرى

يستخدم Ubuntu Apparmor وهذا هو ما يمنعك من الوصول /البيانات /. يستخدم Fedora Selinux وهذا من شأنه أن يمنع هذا على آلة Rhel/Fedora/CentOS.

لتعديل Apparmor للسماح MySQL بالوصول / البيانات / القيام بالمتابعة:

sudo gedit /etc/apparmor.d/usr.sbin.mysqld

أضف هذا الخط في أي مكان في قائمة الدلائل:

/data/ rw,

ثم افعل:

sudo /etc/init.d/apparmor restart

خيار آخر هو تعطيل Apparmor لـ MySQL تمامًا ، هذا هو لا ينصح:

sudo mv /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/

لا تنس إعادة تشغيل Apparmor:

sudo /etc/init.d/apparmor restart

أعلم أنك قلت إنك حاولت بالفعل تحديد أذونات إلى 777 ، لكن بما أن لدي دليلًا على أنه بالنسبة لي ، فقد كانت مشكلة إذن أقوم بنشر ما أديره بالضبط على أمل أن يساعد ذلك. ها هي تجربتي:

tmp $ pwd
/Users/username/tmp
tmp $ mkdir bkptest
tmp $ mysqldump -u root -T bkptest bkptest
mysqldump: Got error: 1: Can't create/write to file '/Users/username/tmp/bkptest/people.txt' (Errcode: 13) when executing 'SELECT INTO OUTFILE'
tmp $ chmod a+rwx bkptest/
tmp $ mysqldump -u root -T bkptest bkptest
tmp $ ls bkptest/
people.sql  people.txt
tmp $ 

MySQL تصبح غبية هنا. يحاول إنشاء ملفات ضمن/tmp/data/.... لذا ما يمكنك فعله هو ما يلي:

mkdir /tmp/data
mount --bind /data /tmp/data

ثم جرب استفسارك. هذا عمل بالنسبة لي بعد ساعات من تصحيح القضية.

كانت هذه المشكلة تزعجني لفترة طويلة. لقد لاحظت أن هذه المناقشة لا تشير إلى الحل على Rhel/Fecora. أنا أستخدم RHEL ولا أجد ملفات التكوين المقابلة لـ Apparmer على Ubuntu ، لكنني قمت بحل مشكلتي عن طريق جعل كل دليل في مسار الدليل قابلاً للقراءة ويمكن الوصول إليه بواسطة MySQL. على سبيل المثال ، إذا قمت بإنشاء دليل /TMP ، فسيتم تحديد الأمر التاليان

chown mysql:mysql /tmp
chmod a+rx /tmp

إذا قمت بإنشاء دليل في الدليل المنزلي /الصفحة الرئيسية /توم ، فيجب عليك القيام بذلك لكل من /المنزل و /المنزل /توم.

يمكنك القيام بالأمر :

mysql -u USERNAME --password=PASSWORD --database=DATABASE --execute='SELECT `FIELD`, `FIELD` FROM `TABLE` LIMIT 0, 10000 ' -X > file.xml

بعض الأشياء التي يجب تجربتها:

  • هل secure_file_priv مجموعة متغير النظام؟ إذا كان الأمر كذلك ، فيجب كتابة جميع الملفات إلى هذا الدليل.
  • تأكد من عدم وجود الملف - سيقوم MySQL بإنشاء ملفات جديدة فقط ، وليس الكتابة فوقها.

لدي نفس المشكلة وحددت هذه المشكلة باتباع الخطوات:

  • نظام التشغيل: Ubuntu 12.04
  • مصباح مثبت
  • افترض أن الدليل الخاص بك لحفظ ملف الإخراج هو:/var/www/csv/

تنفيذ الأمر التالي على Terminal وتحرير هذا الملف باستخدام محرر GEDIT لإضافة دليلك إلى ملف الإخراج.

sudo gedit /etc/apparmor.d/usr.sbin.mysqld

  • سيتم فتح ملف الآن في المحرر الرجاء إضافة الدليل هناك

    /var/www/csv/* rw ،

  • وبالمثل ، أضفت في ملفي ، كما يلي الصورة المعطاة:

enter image description here

تنفيذ الأمر التالي لإعادة تشغيل الخدمات:

sudo /etc/init.d/apparmor إعادة تشغيل

على سبيل المثال أقوم بتنفيذ الاستعلام التالي في منشئ الاستعلام phpmyadmin لإخراج البيانات في ملف CSV

SELECT colName1, colName2,colName3
INTO OUTFILE '/var/www/csv/OUTFILE.csv'
FIELDS TERMINATED BY ','
FROM tableName;

لقد تم القيام به بنجاح واكتب جميع الصفوف مع أعمدة محددة في ملف output.csv ...

في حالتي ، كان الحل هو جعل كل دليل في مسار الدليل قابلاً للقراءة ويمكن الوصول إليه بواسطة mysql (chmod a+rx). كان الدليل لا يزال محددًا بواسطة مساره النسبي في سطر الأوامر.

chmod a+rx /tmp
chmod a+rx /tmp/migration
etc.

لقد واجهت هذه المشكلة نفسها. كانت مشكلتي هي الدليل الذي كنت أحاول إلقاؤه فيه لم يكن لديه إذن الكتابة لعملية MySQLD. سوف يكتب تفريغ SQL الأولي لكن كتابة ملف CSV/TXT ستفشل. يبدو أن تفريغ SQL يتم تشغيله كمستخدم الحالي ويتم تشغيل التحويل إلى CSV/TXT كمستخدم يعمل MySQLD. لذلك يحتاج الدليل إلى أذونات الكتابة لكلا المستخدمين.

تحتاج إلى توفير مسار مطلق ، وليس مسارًا نسبيًا.

وفر المسار الكامل إلى دليل /البيانات التي تحاول الكتابة إليها.

هل يستخدم Ubuntu Selinux؟ تحقق لمعرفة ما إذا كان تم تمكينه وتطبيقه. قد يكون/joog/audit/audit.log مساعدة (إذا كان هذا هو المكان الذي تلتصق به أوبونتو - هذا هو موقع Rhel/Fedora).

واجهت نفس المشكلة على CentOS 6.7 في حالتي تم تعيين جميع الأذونات وما زال يحدث الخطأ. كانت المشكلة أن SE Linux كان في وضع "إنفاذ".

لقد قمت بتبديلها إلى "متساهلة" باستخدام الأمر sudo setenforce 0

ثم كل شيء نجح بالنسبة لي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top