Bazy danych o otwartym kodzie źródłowym szybko stają się głównym nurtem, więc migracja z silników zastrzeżonych do silników o otwartym kodzie źródłowym jest obecnie rodzajem trendu w branży. Oznacza to również, że my, DBA, często musimy zarządzać wieloma backendami baz danych.
W kilku ostatnich wpisach na blogu mój kolega Paul Namuag i ja omówiliśmy kilka aspektów migracji z Oracle do Percony, MariaDB i MySQL. Oczywistym celem migracji jest usprawnienie działania aplikacji w nowym środowisku bazy danych, jednak kluczowe jest zapewnienie, że personel jest gotowy do jej obsługi.
Ten blog opisuje podstawowe operacje MySQL w odniesieniu do podobnych zadań, które można wykonywać codziennie w środowisku Oracle. Zapewnia głębokie zagłębienie się w różne tematy, aby zaoszczędzić czas, ponieważ możesz odnieść się do wiedzy Oracle, którą już zbudowałeś przez lata.
Porozmawiamy również o zewnętrznych narzędziach wiersza poleceń, których brakuje w domyślnej instalacji MySQL, ale są one potrzebne do wydajnego wykonywania codziennych operacji. Wersja open source nie zawiera na przykład odpowiednika Oracle Cloud Control, więc sprawdź ClusterControl, jeśli szukasz czegoś podobnego.
W tym blogu zakładamy, że masz lepszą wiedzę na temat Oracle niż MySQL i dlatego chciałbyś poznać korelację między nimi. Przykłady są oparte na platformie Linux, jednak można znaleźć wiele podobieństw w zarządzaniu MySQL w systemie Windows.
Jak połączyć się z MySQL?
Zacznijmy naszą podróż od bardzo (pozornie) podstawowego zadania. Właściwie jest to rodzaj zadania, które może powodować pewne zamieszanie ze względu na różne koncepcje logowania w Oracle i MySQL.
Odpowiednikiem sqlplus / jako połączenie sysdba jest polecenie terminala „mysql” z flagą -uroot. W świecie MySQL superużytkownik nazywa się root. Użytkownicy bazy danych MySQL (w tym root) są definiowani przez nazwę i hosta, z którego mogą się łączyć.
Informacje o użytkowniku i hostach, z których może się połączyć, są przechowywane w tabeli mysql.user. Podczas próby połączenia MySQL sprawdza, czy host klienta, nazwa użytkownika i hasło pasują do wiersza w tabeli metadanych.
To trochę inne podejście niż w Oracle, gdzie mamy tylko nazwę użytkownika i hasło, ale ci, którzy są zaznajomieni z Oracle Connection Manager, mogą znaleźć pewne podobieństwa.
Nie znajdziesz predefiniowanych wpisów TNS jak w Oracle. Zwykle do połączenia administratora potrzebujemy użytkownika, hasła i flagi -h hosta. Domyślny port to 3306 (jak 1521 w Oracle), ale może się to różnić w zależności od konfiguracji.
Domyślnie wiele instalacji będzie mieć zablokowane połączenie z dostępem do roota z dowolnego komputera ([email protected]’%’), więc musisz zalogować się na serwerze hostującym MySQL, zazwyczaj przez ssh.
Wpisz następujące:
mysql -u root
Jeśli hasło roota nie jest ustawione, to wystarczy. Jeśli hasło jest wymagane, należy dodać flagę -p.
mysql -u root -p
Jesteś teraz zalogowany do klienta mysql (odpowiednik sqlplus) i zobaczysz monit, zwykle „mysql>”.
Czy MySQL działa i działa?
Możesz użyć skryptu startowego usługi mysql lub polecenia mysqladmin, aby sprawdzić, czy jest uruchomiona. Następnie możesz użyć polecenia ps, aby sprawdzić, czy procesy mysql są uruchomione i działają. Inną alternatywą może być mysqladmin, narzędzie służące do wykonywania operacji administracyjnych.
mysqladmin -u root -p status
W Debianie:
/etc/init.d/mysql status
Jeśli używasz RedHat lub Fedory, możesz użyć następującego skryptu:
service mysqld status
Lub
/etc/init.d/mysqld status
Lub
systemctl status mysql.service
W instancjach MariaDB powinieneś poszukać nazwy usługi MariaDB.
systemctl status mariadb
Co znajduje się w tej bazie danych?
Podobnie jak w Oracle, możesz odpytywać obiekty metadanych, aby uzyskać informacje o obiektach bazy danych.
Często używa się tutaj skrótów, poleceń, które pomagają wyświetlić listę obiektów lub uzyskać DDL obiektów.
show databases;
use database_name;
show tables;
show table status;
show index from table_name;
show create table table_name;
Podobnie jak w Oracle, możesz opisać tabelę:
desc table_name;
Gdzie są przechowywane moje dane?
W MySQL nie ma dedykowanej pamięci wewnętrznej, takiej jak ASM. Wszystkie pliki danych są umieszczane w zwykłych punktach montowania systemu operacyjnego. Przy domyślnej instalacji możesz znaleźć swoje dane w:
/var/lib/mysql
Lokalizacja jest oparta na zmiennej datadir.
[email protected]:~# cat /etc/mysql/my.cnf | grep datadir
datadir=/var/lib/mysql
Zobaczysz tam katalog dla każdej bazy danych.
W zależności od wersji i silnika magazynu (tak jest ich tutaj kilka) katalog bazy danych może zawierać pliki w formacie *.frm, które definiują strukturę każdej tabeli w bazie danych. W przypadku tabel MyISAM dane (*.MYD) i indeksy (*.MYI) są również przechowywane w tym katalogu.
Tabele InnoDB są przechowywane w przestrzeniach tabel InnoDB. Każdy z nich składa się z jednego lub więcej plików, które są podobne do obszarów tabel Oracle. W domyślnej instalacji wszystkie dane i indeksy InnoDB dla wszystkich baz danych na serwerze MySQL są przechowywane w jednym obszarze tabel, składającym się z jednego pliku:/var/lib/mysql/ibdata1. W większości konfiguracji nie zarządzasz obszarami tabel, jak w Oracle. Najlepszą praktyką jest utrzymywanie ich z włączonym automatycznym rozszerzeniem i nieograniczonym maksymalnym rozmiarem.
[email protected]:~# cat /etc/mysql/my.cnf | grep innodb-data-file-path
innodb-data-file-path = ibdata1:100M:autoextend
InnoDB ma pliki dziennika, które są odpowiednikiem dzienników przeróbek Oracle, umożliwiając automatyczne odzyskiwanie po awarii. Domyślnie istnieją dwa pliki dziennika:/var/lib/mysql/ib_logfile0 i /var/lib/mysql/ib_logfile1. Dane cofania są przechowywane w pliku przestrzeni tabel.
[email protected]:/var/lib/mysql# ls -rtla | grep logfile
-rw-rw---- 1 mysql mysql 268435456 Dec 15 00:59 ib_logfile1
-rw-rw---- 1 mysql mysql 268435456 Mar 6 11:45 ib_logfile0
Gdzie są informacje o metadanych?
Nie ma widoków typu dba_*, user_*, all_*, ale MySQL ma wewnętrzne widoki metadanych.
Schemat_informacji jest zdefiniowany w standardzie SQL 2003 i jest implementowany przez inne liczące się bazy danych, m.in. SQL Server, PostgreSQL.
Od MySQL 5.0 dostępna jest baza danych information_schema, zawierająca informacje ze słownika danych. Informacje były faktycznie przechowywane w zewnętrznych plikach FRM. Wreszcie po wielu latach pliki .frm zniknęły w wersji 8.0. Metadane są nadal widoczne w bazie danych information_schema, ale korzystają z silnika przechowywania InnoDB.
Aby zobaczyć wszystkie aktualne widoki zawarte w słowniku danych w kliencie mysql, przejdź do bazy danych information_schema:
use information_schema;
show tables;
Możesz znaleźć dodatkowe informacje w bazie danych MySQL, która zawiera informacje o bazie danych, zdarzeniu (zadaniach MySQL), wtyczkach, replikacji, bazie danych, użytkownikach itp.
Liczba wyświetleń zależy od wersji i dostawcy.
Wybierz * z v$sesji
Select * Oracle z v$session jest tutaj reprezentowany przez polecenie SHOW PROCESSLIST, które pokazuje listę wątków.
mysql> SHOW PROCESSLIST;
+---------+------------------+------------------+--------------------+---------+--------+--------------------+------------------+-----------+---------------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined |
+---------+------------------+------------------+--------------------+---------+--------+--------------------+------------------+-----------+---------------+
| 1 | system user | | NULL | Sleep | 469264 | wsrep aborter idle | NULL | 0 | 0 |
| 2 | system user | | NULL | Sleep | 469264 | NULL | NULL | 0 | 0 |
| 3 | system user | | NULL | Sleep | 469257 | NULL | NULL | 0 | 0 |
| 4 | system user | | NULL | Sleep | 469257 | NULL | NULL | 0 | 0 |
| 6 | system user | | NULL | Sleep | 469257 | NULL | NULL | 0 | 0 |
| 16 | maxscale | 10.0.3.168:5914 | NULL | Sleep | 5 | | NULL | 4 | 4 |
| 59 | proxysql-monitor | 10.0.3.168:6650 | NULL | Sleep | 7 | | NULL | 0 | 0 |
| 81 | proxysql-monitor | 10.0.3.78:62896 | NULL | Sleep | 6 | | NULL | 0 | 0 |
| 1564 | proxysql-monitor | 10.0.3.78:25064 | NULL | Sleep | 3 | | NULL | 0 | 0 |
| 1822418 | cmon | 10.0.3.168:41202 | information_schema | Sleep | 0 | | NULL | 0 | 8 |
| 1822631 | cmon | 10.0.3.168:43254 | information_schema | Sleep | 4 | | NULL | 1 | 1 |
| 1822646 | cmon | 10.0.3.168:43408 | information_schema | Sleep | 0 | | NULL | 464 | 464 |
| 2773260 | backupuser | localhost | mysql | Query | 0 | init | SHOW PROCESSLIST | 0 | 0 |
+---------+------------------+------------------+--------------------+---------+--------+--------------------+------------------+-----------+---------------+
13 rows in set (0.00 sec)
Opiera się na informacjach przechowywanych w widoku information_schema.processlist. Widok wymaga uprawnienia PROCESS. Może również pomóc w sprawdzeniu, czy kończy Ci się maksymalna liczba procesów.
Gdzie jest dziennik alertów?
Dziennik błędów można znaleźć w my.cnf lub za pomocą polecenia pokaż zmienne.
mysql> show variables like 'log_error';
+---------------+--------------------------+
| Variable_name | Value |
+---------------+--------------------------+
| log_error | /var/lib/mysql/error.log |
+---------------+--------------------------+
1 row in set (0.00 sec)
Gdzie jest lista użytkowników i ich uprawnień?
Informacje o użytkownikach są przechowywane w tabeli mysql.user, natomiast dotacje są przechowywane w kilku miejscach, w tym w mysql.user, mysql.tables_priv,
Dostęp użytkownika MySQL jest zdefiniowany w:
mysql.columns_priv, mysql.tables_priv, mysql.db,mysql.user
Najlepszym sposobem na wyświetlenie listy grantów jest użycie pt-grants, narzędzia z zestawu narzędzi Percona (niezbędne dla każdego DBA MySQL).
pt-show-grants --host localhost --user root --ask-pass
Alternatywnie możesz użyć następującego zapytania (stworzonego przez Calvaldo)
SELECT
CONCAT("`",gcl.Db,"`") AS 'Database(s) Affected',
CONCAT("`",gcl.Table_name,"`") AS 'Table(s) Affected',
gcl.User AS 'User-Account(s) Affected',
IF(gcl.Host='%','ALL',gcl.Host) AS 'Remote-IP(s) Affected',
CONCAT("GRANT ",UPPER(gcl.Column_priv)," (",GROUP_CONCAT(gcl.Column_name),") ",
"ON `",gcl.Db,"`.`",gcl.Table_name,"` ",
"TO '",gcl.User,"'@'",gcl.Host,"';") AS 'GRANT Statement (Reconstructed)'
FROM mysql.columns_priv gcl
GROUP BY CONCAT(gcl.Db,gcl.Table_name,gcl.User,gcl.Host)
/* SELECT * FROM mysql.columns_priv */
UNION
/* [Database.Table]-Specific Grants */
SELECT
CONCAT("`",gtb.Db,"`") AS 'Database(s) Affected',
CONCAT("`",gtb.Table_name,"`") AS 'Table(s) Affected',
gtb.User AS 'User-Account(s) Affected',
IF(gtb.Host='%','ALL',gtb.Host) AS 'Remote-IP(s) Affected',
CONCAT(
"GRANT ",UPPER(gtb.Table_priv)," ",
"ON `",gtb.Db,"`.`",gtb.Table_name,"` ",
"TO '",gtb.User,"'@'",gtb.Host,"';"
) AS 'GRANT Statement (Reconstructed)'
FROM mysql.tables_priv gtb
WHERE gtb.Table_priv!=''
/* SELECT * FROM mysql.tables_priv */
UNION
/* Database-Specific Grants */
SELECT
CONCAT("`",gdb.Db,"`") AS 'Database(s) Affected',
"ALL" AS 'Table(s) Affected',
gdb.User AS 'User-Account(s) Affected',
IF(gdb.Host='%','ALL',gdb.Host) AS 'Remote-IP(s) Affected',
CONCAT(
'GRANT ',
CONCAT_WS(',',
IF(gdb.Select_priv='Y','SELECT',NULL),
IF(gdb.Insert_priv='Y','INSERT',NULL),
IF(gdb.Update_priv='Y','UPDATE',NULL),
IF(gdb.Delete_priv='Y','DELETE',NULL),
IF(gdb.Create_priv='Y','CREATE',NULL),
IF(gdb.Drop_priv='Y','DROP',NULL),
IF(gdb.Grant_priv='Y','GRANT',NULL),
IF(gdb.References_priv='Y','REFERENCES',NULL),
IF(gdb.Index_priv='Y','INDEX',NULL),
IF(gdb.Alter_priv='Y','ALTER',NULL),
IF(gdb.Create_tmp_table_priv='Y','CREATE TEMPORARY TABLES',NULL),
IF(gdb.Lock_tables_priv='Y','LOCK TABLES',NULL),
IF(gdb.Create_view_priv='Y','CREATE VIEW',NULL),
IF(gdb.Show_view_priv='Y','SHOW VIEW',NULL),
IF(gdb.Create_routine_priv='Y','CREATE ROUTINE',NULL),
IF(gdb.Alter_routine_priv='Y','ALTER ROUTINE',NULL),
IF(gdb.Execute_priv='Y','EXECUTE',NULL),
IF(gdb.Event_priv='Y','EVENT',NULL),
IF(gdb.Trigger_priv='Y','TRIGGER',NULL)
),
" ON `",gdb.Db,"`.* TO '",gdb.User,"'@'",gdb.Host,"';"
) AS 'GRANT Statement (Reconstructed)'
FROM mysql.db gdb
WHERE gdb.Db != ''
/* SELECT * FROM mysql.db */
UNION
/* User-Specific Grants */
SELECT
"ALL" AS 'Database(s) Affected',
"ALL" AS 'Table(s) Affected',
gus.User AS 'User-Account(s) Affected',
IF(gus.Host='%','ALL',gus.Host) AS 'Remote-IP(s) Affected',
CONCAT(
"GRANT ",
IF((gus.Select_priv='N')&(gus.Insert_priv='N')&(gus.Update_priv='N')&(gus.Delete_priv='N')&(gus.Create_priv='N')&(gus.Drop_priv='N')&(gus.Reload_priv='N')&(gus.Shutdown_priv='N')&(gus.Process_priv='N')&(gus.File_priv='N')&(gus.References_priv='N')&(gus.Index_priv='N')&(gus.Alter_priv='N')&(gus.Show_db_priv='N')&(gus.Super_priv='N')&(gus.Create_tmp_table_priv='N')&(gus.Lock_tables_priv='N')&(gus.Execute_priv='N')&(gus.Repl_slave_priv='N')&(gus.Repl_client_priv='N')&(gus.Create_view_priv='N')&(gus.Show_view_priv='N')&(gus.Create_routine_priv='N')&(gus.Alter_routine_priv='N')&(gus.Create_user_priv='N')&(gus.Event_priv='N')&(gus.Trigger_priv='N')&(gus.Create_tablespace_priv='N')&(gus.Grant_priv='N'),
"USAGE",
IF((gus.Select_priv='Y')&(gus.Insert_priv='Y')&(gus.Update_priv='Y')&(gus.Delete_priv='Y')&(gus.Create_priv='Y')&(gus.Drop_priv='Y')&(gus.Reload_priv='Y')&(gus.Shutdown_priv='Y')&(gus.Process_priv='Y')&(gus.File_priv='Y')&(gus.References_priv='Y')&(gus.Index_priv='Y')&(gus.Alter_priv='Y')&(gus.Show_db_priv='Y')&(gus.Super_priv='Y')&(gus.Create_tmp_table_priv='Y')&(gus.Lock_tables_priv='Y')&(gus.Execute_priv='Y')&(gus.Repl_slave_priv='Y')&(gus.Repl_client_priv='Y')&(gus.Create_view_priv='Y')&(gus.Show_view_priv='Y')&(gus.Create_routine_priv='Y')&(gus.Alter_routine_priv='Y')&(gus.Create_user_priv='Y')&(gus.Event_priv='Y')&(gus.Trigger_priv='Y')&(gus.Create_tablespace_priv='Y')&(gus.Grant_priv='Y'),
"ALL PRIVILEGES",
CONCAT_WS(',',
IF(gus.Select_priv='Y','SELECT',NULL),
IF(gus.Insert_priv='Y','INSERT',NULL),
IF(gus.Update_priv='Y','UPDATE',NULL),
IF(gus.Delete_priv='Y','DELETE',NULL),
IF(gus.Create_priv='Y','CREATE',NULL),
IF(gus.Drop_priv='Y','DROP',NULL),
IF(gus.Reload_priv='Y','RELOAD',NULL),
IF(gus.Shutdown_priv='Y','SHUTDOWN',NULL),
IF(gus.Process_priv='Y','PROCESS',NULL),
IF(gus.File_priv='Y','FILE',NULL),
IF(gus.References_priv='Y','REFERENCES',NULL),
IF(gus.Index_priv='Y','INDEX',NULL),
IF(gus.Alter_priv='Y','ALTER',NULL),
IF(gus.Show_db_priv='Y','SHOW DATABASES',NULL),
IF(gus.Super_priv='Y','SUPER',NULL),
IF(gus.Create_tmp_table_priv='Y','CREATE TEMPORARY TABLES',NULL),
IF(gus.Lock_tables_priv='Y','LOCK TABLES',NULL),
IF(gus.Execute_priv='Y','EXECUTE',NULL),
IF(gus.Repl_slave_priv='Y','REPLICATION SLAVE',NULL),
IF(gus.Repl_client_priv='Y','REPLICATION CLIENT',NULL),
IF(gus.Create_view_priv='Y','CREATE VIEW',NULL),
IF(gus.Show_view_priv='Y','SHOW VIEW',NULL),
IF(gus.Create_routine_priv='Y','CREATE ROUTINE',NULL),
IF(gus.Alter_routine_priv='Y','ALTER ROUTINE',NULL),
IF(gus.Create_user_priv='Y','CREATE USER',NULL),
IF(gus.Event_priv='Y','EVENT',NULL),
IF(gus.Trigger_priv='Y','TRIGGER',NULL),
IF(gus.Create_tablespace_priv='Y','CREATE TABLESPACE',NULL)
)
)
),
" ON *.* TO '",gus.User,"'@'",gus.Host,"' REQUIRE ",
CASE gus.ssl_type
WHEN 'ANY' THEN
"SSL "
WHEN 'X509' THEN
"X509 "
WHEN 'SPECIFIED' THEN
CONCAT_WS("AND ",
IF((LENGTH(gus.ssl_cipher)>0),CONCAT("CIPHER '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL),
IF((LENGTH(gus.x509_issuer)>0),CONCAT("ISSUER '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL),
IF((LENGTH(gus.x509_subject)>0),CONCAT("SUBJECT '",CONVERT(gus.ssl_cipher USING utf8),"' "),NULL)
)
ELSE "NONE "
END,
"WITH ",
IF(gus.Grant_priv='Y',"GRANT OPTION ",""),
"MAX_QUERIES_PER_HOUR ",gus.max_questions," ",
"MAX_CONNECTIONS_PER_HOUR ",gus.max_connections," ",
"MAX_UPDATES_PER_HOUR ",gus.max_updates," ",
"MAX_USER_CONNECTIONS ",gus.max_user_connections,
";"
) AS 'GRANT Statement (Reconstructed)'
FROM mysql.user gus;
Jak stworzyć użytkownika mysql
Procedura „utwórz użytkownika” jest podobna do Oracle. Najprostszym przykładem może być:
CREATE user 'username'@'hostname' identified by 'password';
GRANT privilege_name on *.* TO 'username'@'hostname';
Opcja przyznawania i tworzenia w jednym wierszu za pomocą:
GRANT privilege_name ON *.* TO 'username'@'hostname' identified by 'password';
został usunięty w MySQL 8.0.
Jak uruchomić i zatrzymać MySQL?
Możesz zatrzymać i uruchomić MySQL z tą usługą.
Rzeczywiste polecenie zależy od dystrybucji Linuksa i nazwy usługi.
Poniżej znajdziesz przykład z nazwą usługi mysqld.
Ubuntu
/etc/init.d/mysqld start
/etc/init.d/mysqld stop
/etc/init.d/mysqld restart
RedHat/Centos
service mysqld start
service mysqld stop
service mysqld restart
systemctl start mysqld.service
systemctl stop mysqld.service
systemctl restart mysqld.service
Gdzie są dane konfiguracyjne serwera MySQL?
Konfiguracja jest przechowywana w pliku my.cnf.
Do wersji 8.0 każda zmiana ustawień dynamicznych, która powinna pozostać po ponownym uruchomieniu, wymagała ręcznej aktualizacji pliku my.cnf. Podobnie jak w przypadku scope=oba w Oracle, możesz zmienić wartości za pomocą opcji trwałej.
mysql> SET PERSIST max_connections = 1000;
mysql> SET @@PERSIST.max_connections = 1000;
W przypadku starszych wersji użyj:
mysql> SET GLOBAL max_connections = 1000;
$ vi /etc/mysql/my.cnf
SET GLOBAL max_connections = 1000;
Jak wykonać kopię zapasową MySQL?
Istnieją dwa sposoby wykonania kopii zapasowej mysql.
W przypadku mniejszych baz danych lub mniejszych selektywnych kopii zapasowych możesz użyć polecenia mysqldump.
Kopia zapasowa bazy danych z mysqldump (logiczna kopia zapasowa):
mysqldump -uuser -p --databases db_name --routines --events --single-transaction | gzip > db_name_backup.sql.gz
xtrabackup, mariabackup (gorąca kopia zapasowa binarna)
Preferowaną metodą jest użycie zewnętrznych narzędzi xtrabackup lub mariabackup do uruchamiania gorących kopii zapasowych.
Oracle oferuje gorące binarne kopie zapasowe w płatnej wersji o nazwie MySQL Enterprise Edition.
mariabackup --user=root --password=PASSWORD --backup --target-dir=/u01/backups/
Przesyłaj kopie zapasowe na inny serwer
Uruchom słuchacz na zewnętrznym serwerze na preferowanym porcie (w tym przykładzie 1984)
nc -l 1984 | pigz -cd - | pv | xbstream -x -C /u01/backups
Uruchom kopię zapasową i przenieś do zewnętrznego hosta
innobackupex --user=root --password=PASSWORD --stream=xbstream /var/tmp | pigz | pv | nc external_host.com 1984
Kopiuj uprawnienia użytkownika
Często konieczne jest skopiowanie uprawnień użytkownika i przeniesienie ich na inne serwery.
Zalecanym sposobem na to jest użycie pt-show-grants.
pt-show-grants > /u01/backups
Jak przywrócić MySQL?
Przywracanie kopii zapasowej logicznej
MySQLdump tworzy plik SQL, który można wykonać za pomocą polecenia źródłowego.
Aby zachować plik dziennika wykonania, użyj polecenia tee.
mysql> tee dump.log
mysql> source mysqldump.sql
Przywracanie kopii zapasowej binarnej (xtrabackup/mariabackup)
Aby przywrócić MySQL z binarnej kopii zapasowej, musisz najpierw przywrócić pliki, a następnie zastosować pliki dziennika.
Możesz porównać ten proces, aby przywrócić i odzyskać w Oracle.
xtrabackup --copy-back --target-dir=/var/lib/data
innobackupex --apply-log --use-memory=[values in MB or GB] /var/lib/data
Mamy nadzieję, że te wskazówki dają dobry przegląd sposobu wykonywania podstawowych zadań administracyjnych.