Zrzuć bazę danych mysql do kopii zapasowej w postaci zwykłego tekstu (CSV) z wiersza poleceń

93

Chciałbym uniknąć mysqldump, ponieważ generuje on dane w formie, która jest wygodna do czytania tylko dla mysql. CSV wydaje się bardziej uniwersalny (wystarczy jeden plik na tabelę). Ale jeśli mysqldump ma zalety, to mam uszy. Chciałbym również coś, co mogę uruchomić z wiersza poleceń (linux). Jeśli to jest skrypt mysql, pomocne byłyby wskazówki, jak zrobić coś takiego.

dreeves
źródło

Odpowiedzi:

141

Jeśli możesz sobie poradzić z tabelą w czasie, a Twoje dane nie są binarne, użyj -Bopcji mysqlpolecenia. Dzięki tej opcji wygeneruje pliki TSV (oddzielone tabulatorami), które można łatwo zaimportować do programu Excel itp .:

% echo 'SELECT * FROM table' | mysql -B -uxxx -pyyy database

Alternatywnie, jeśli masz bezpośredni dostęp do systemu plików serwera, użyj narzędzia, SELECT INTO OUTFILEktóre może wygenerować prawdziwe pliki CSV:

SELECT * INTO OUTFILE 'table.csv'
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
    LINES TERMINATED BY '\n'
FROM table
Alnitak
źródło
dzięki! Twoja druga „tabela” powinna być „bazą danych”, prawda? nie ma opcji dla CSV zamiast TSV, o którym wiesz?
dreeves
duh - tak, powinno było czytać „bazę danych”. Nie, nie ma opcji dla CSV, jest to najlepsza opcja, jaką znam bez użycia wbudowanego MySQL-a „select into outfile”, który może zrobić CSV, ale zapisuje pliki na serwerze, a nie na kliencie.
Alnitak
jak wymusić nadpisanie w pliku wyjściowym?
JCm
11
Zwróć uwagę, że gdy podana jest ścieżka względna (lub po prostu nazwa pliku), plik pojawi się w katalogu MYSQL, a nie w bieżącym katalogu powłoki (tj. W miejscu, \. file.sqlz którego czyta). W związku z tym, w zależności od instalacji, prawdopodobnie znajdziesz ją pod adresem/var/lib/mysql/[db_name]/table.csv
Mała
32

W samym MySQL możesz określić dane wyjściowe CSV, takie jak:

SELECT order_id,product_name,qty
FROM orders
INTO OUTFILE '/tmp/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'

Z http://www.tech-recipes.com/rx/1475/save-mysql-query-results-into-a-text-or-csv-file/

Paul Tomblin
źródło
2
Nie mogę znaleźć zrzuconego pliku w podanym przeze mnie katalogu, dlaczego tak jest?
JCm
@JCm zrzuca na serwer
Alnitak
26

Dzięki opcji możesz zrzucić całą bazę danych za jednym razem mysqldump's --tab. Podajesz ścieżkę do katalogu i tworzy jeden .sqlplik ze CREATE TABLE DROP IF EXISTSskładnią i .txtplik z zawartością rozdzieloną tabulatorami. Aby utworzyć pliki oddzielone przecinkami, możesz użyć:

mysqldump --password  --fields-optionally-enclosed-by='"' --fields-terminated-by=',' --tab /tmp/path_to_dump/ database_name

Ta ścieżka musi być zapisywalna zarówno przez użytkownika mysql, jak i użytkownika uruchamiającego polecenie, więc dla uproszczenia zalecam chmod 777 /tmp/path_to_dump/najpierw.

chmac
źródło
1
Wracałem do tej odpowiedzi, to zdecydowanie najlepszy sposób na wyeksportowanie wszystkich tabel do rozdzielanego pliku.
joevallender
mysqldump: You must use option --tab with --fields-...
Marco Marsala
Jako root: GRANT FILE ON *.* TO 'user1'@'localhost';- stackoverflow.com/a/15014385/1707015 . W moim przypadku musiałem wziąć /var/lib/mysql-files/(zamiast /tmp/) ustawić użytkownika na mysql: mysql i ustawić uprawnienia na 777 - stackoverflow.com/a/32737616/1707015 .
qräbnö
18

Opcja wyboru do pliku wyjściowego nie zadziała dla mnie, ale poniższy okrężny sposób przesyłania pliku rozdzielanego tabulatorami przez SED zadziałał:

mysql -uusername -ppassword -e "SELECT * from tablename" dbname | sed 's/\t/","/g;s/^/"/;s/$/"/' > /path/to/file/filename.csv
Sri
źródło
1
To polecenie spowodowało tzastąpienie litery ", "w pliku wyjściowym. Nie do końca o to mi chodziło.
BrennanR
9

Oto najprostsze polecenie

mysql -h<hostname> -u<username> -p<password> -e 'select * from databaseName.tableNaame' | sed  's/\t/,/g' > output.csv

Jeśli w wartości kolumny znajduje się przecinek, możemy wygenerować .tsv zamiast .csv za pomocą następującego polecenia

mysql -h<hostname> -u<username> -p<password> -e 'select * from databaseName.tableNaame' > output.csv
minhas23
źródło
Dla CSV: działa tam, gdzie potrzebuję tylko przecinka. mysql -hlocalhost -uroot -e 'select * from databaseName.tableNaame' | sed 's/\t/,/g' > /tmp/output.csv`
3

Jeśli naprawdę potrzebujesz „kopii zapasowej”, potrzebujesz również schematu bazy danych, takiego jak definicje tabel, definicje widoków, procedury przechowywania i tak dalej. Kopia zapasowa bazy danych to nie tylko dane.

Wartość formatu mysqldump do tworzenia kopii zapasowych polega w szczególności na tym, że jest bardzo ŁATWY w użyciu do przywracania baz danych mysql. Kopia zapasowa, której nie można łatwo przywrócić, jest znacznie mniej przydatna. Jeśli szukasz metody niezawodnej kopii zapasowej danych mysql, aby można było przywrócić je na serwer mysql, to myślę, że powinieneś pozostać przy narzędziu mysqldump.

MySQL jest darmowy i działa na wielu różnych platformach. Konfiguracja nowego serwera mysql, do którego mogę przywrócić, jest prosta. W ogóle nie martwię się, że nie będę w stanie skonfigurować mysql, więc mogę przywrócić.

Znacznie bardziej martwiłbym się niestandardową kopią zapasową / przywracaniem opartą na kruchym formacie, takim jak csv / tsv. Czy na pewno wszystkie cudzysłowy, przecinki lub tabulatory, które znajdują się w Twoich danych, zostaną poprawnie zmienione, a następnie poprawnie przeanalizowane przez narzędzie przywracania?

Jeśli szukasz metody wyodrębnienia danych, zobacz kilka w innych odpowiedziach.

Zoredache
źródło
dzięki, bardzo pomocne! przekonałeś mnie. Mam jednak inne powody, by chcieć w szybki sposób uzyskać zrzut csv za pomocą polecenia wiersza poleceń. domagam się „zaakceptowanej odpowiedzi”. (chociaż prawdopodobnie mógłbym w tym momencie poskładać to razem z bieżących odpowiedzi, myślę, że w / w skrypt mysql).
dreeves
Widzę dużą wartość w posiadaniu zarówno kopii zapasowej przy użyciu metody natywnej, jak i ekstrakcji do innych celów.
Zoredache
mk-parallel-restore może przywrócić kopię zapasową CSV utworzoną za pomocą mk-parallel dump, dzięki czemu możesz uzyskać to, co najlepsze z obu światów. W rzeczywistości mk-parallel-restore działa lepiej, zapewniając, że wszelkie zdefiniowane wyzwalacze zostaną przywrócone jako ostatnie.
Paul Dixon
3

Możesz użyć poniższego skryptu, aby uzyskać dane wyjściowe do plików csv. Jeden plik na tabelę z nagłówkami.

for tn in `mysql --batch --skip-page --skip-column-name --raw -uuser -ppassword -e"show tables from mydb"`
do 
mysql -uuser -ppassword mydb -B -e "select * from \`$tn\`;" | sed 's/\t/","/g;s/^/"/;s/$/"/;s/\n//g' > $tn.csv
done

user to twoja nazwa użytkownika, password to hasło, jeśli nie chcesz ciągle wpisywać hasła dla każdej tabeli, a mydb to nazwa bazy danych.

Wyjaśnienie skryptu: pierwsze wyrażenie w sedzie zamieni tabulatory na „,”, więc masz pola ujęte w podwójne cudzysłowy i oddzielone przecinkami. Druga wstawia podwójny cudzysłów na początku, a trzecia podwójny cudzysłów na końcu. A ostatnia zajmuje się \ n.

Kiran Pathuru
źródło
To głównie doprowadziło mnie do miejsca, w którym musiałem iść, ale byłem zaskoczony, gdy litera „t” została zastąpiona przecinkami: stackoverflow.com/a/2610121/8400969
Michael
I to powinno powiedzieć również --skip-column-namesw mojej wersji mysql
Michael
2

Sprawdź mk-parallel-dump, który jest częścią zawsze przydatnego zestawu narzędzi maatkit . Może to zrzucić pliki rozdzielane przecinkami z opcją --csv.

Może to zrobić całą bazę danych bez określania pojedynczych tabel, a także możesz określić grupy tabel w tabeli zestawu kopii zapasowych.

Zwróć uwagę, że zrzuca również definicje tabel, widoki i wyzwalacze do oddzielnych plików. Oprócz zapewnienia pełnej kopii zapasowej w bardziej powszechnie dostępnej formie, można ją również natychmiast przywrócić dzięki przywracaniu równoległemu mk

Paul Dixon
źródło
To może nie być idealna kopia zapasowa, ale jest całkowicie świetna do udostępniania. Dziękuję Ci!
atroon
maatkitwydaje się być częścią percona toolkitteraźniejszości, ale nie mogę znaleźć odpowiednich narzędzi.
sjas
1

Dwuliniowa odpowiedź PowerShell:

# Store in variable
$Global:csv = (mysql -uroot -p -hlocalhost -Ddatabase_name -B -e "SELECT * FROM some_table") `
| ConvertFrom-Csv -Delimiter "`t"

# Out to csv
$Global:csv | Export-Csv "C:\temp\file.csv" -NoTypeInformation

Boom-bata-boom

-D = nazwa twojej bazy danych

-e = zapytanie

-B = rozdzielany znakami tabulacji

Kolob Canyon
źródło
1

Jeśli chcesz zrzucić całą bazę danych jako csv

#!/bin/bash

host=hostname
uname=username
pass=password

port=portnr
db=db_name
s3_url=s3://bxb2-anl-analyzed-pue2/bxb_ump/db_dump/



DATE=`date +%Y%m%d`
rm -rf $DATE

echo 'show tables' | mysql -B -h${host} -u${uname} -p${pass} -P${port} ${db} > tables.txt
awk 'NR>1' tables.txt > tables_new.txt

while IFS= read -r line
do
  mkdir -p $DATE/$line
  echo "select * from $line" | mysql -B -h"${host}" -u"${uname}" -p"${pass}" -P"${port}" "${db}" > $DATE/$line/dump.tsv
done < tables_new.txt

touch $DATE/$DATE.fin


rm -rf tables_new.txt tables.txt
veera
źródło