O conceito de tablespace não tem nada de novo. Só não é mais velho que eu. Vários outros RDBMS (bancos de dados) o implementam faz algum tempo. No MySQL foi implementado pelos primórdios do innoDB.

Em linhas gerais o que é uma tablespace?
Tem algumas palavras em inglês que não fazem o menor sentido traduzidas, ou, em traduzi-las. Concorda comigo? Para mim, tablespace é uma dessas palavras. Vamos lá: “espaço de tabelas”. Tablespace é uma área, física e/ou lógica, na qual se aglomeram uma ou mais tabelas. É como se fosse uma área reservada para uma, ou, um grupo de tabelas. Seja com o objetivo de organização (tabelas com mesmo fim, aplicação, etc), volumetria, performance, segurança, etc.

O MySQL e sua épica jornada com tablespaces
No princípio de tudo, e até a chegada da versão 5.1, todas as tabelas com storage engine innoDB eram, compulsoriamente, criadas dentro de uma tablespace única, também chamada de compartilhada (shared tablespace). Fisicamente, consistia de um arquivo com síndrome de Buzz (pois, crescia ao infinito e além), de nome ibdata, que, ficava logo abaixo da raiz do DATADIR (diretório de dados, definido pela variável datadir, e, onde reside o schema do MySQL). Esta implementação me rendeu muitas horas de sono, pois, era uma verdadeira armadilha. Por ser um único arquivo contendo várias tabelas, apresentava contenções de S/O, era de difícil sustentação e manutenção.

Com o advento da versão 5.1, o MySQL implementou, desesperadamente, a possibilidade de cada tabela apresentar-se fisicamente à sua própria tablespace. Para quem está perdido no assunto, consulte a variável innodb_file_per_table. Então, como cada tablespace armazenaria uma única tabela, houve um ganho exponencial, tais como: maior performance, shrink (encolhimento, ou, reclamar espaço de linhas apagadas) muitas vezes melhorado, redução de contenção a nível de SO, menor espaço total da massa de dados, entre outros. No entanto, agora com muitos mais arquivos físicos, maior a necessidade de olhar com carinho a configuração do SO, para não estourar, a quantidade máxima de arquivos abertos por processo (file descriptors).

Enquanto escrevo este artigo, meu cachorro Rodolpho está mordendo tudo ao seu alcance (inclusive eu), paralelamente, o MySQL 5.7 em subversão 7 (5.7.7) RC (release candidate), em vias de sair do forno e ganhar as ruas. Agora, muito melhorada, as tablespaces são mais racionais, de manutenção ampliada, e mais configurável. No entanto, o que mais se destaca é a possibilidade de se utilizar, simultaneamente: tablespace exclusiva para cada tabela, e, tablespace compartilhada. E mais, agora, podemos agrupar, de fato, determinadas tabelas em uma dada tablespace, possibilitando assim, diminuir a quantidade de file descriptors consumidos. Além, de organizar as tabelas por tipo/quantidade de acesso, volume, aplicação. De fato, já fazemos isso no Oracle há algum tempo, então, apesar da empolgação, não é, verdadeiramente, algo novo, mas, solicitado à exaustão à equipe de desenvolvedores. Outra coisa bacana, é que agora é possível determinar o local físico de cada tablespace. Isso mesmo, você poderia, por exemplo, colocar tablespace em um determinado storage, melhorando, ainda mais, a performance.

Mãos obras, brincar com a novidade
Vou utilizar a famosa base de dados world, que pode ser baixada clicando aqui.

Criando uma tablespace novinha em folha:

CREATE TABLESPACE tablespace_5_7 ADD DATAFILE ‘tablespace_5_7_dbf.ibd’;

Para criar em outro ponto de montagem:

CREATE TABLESPACE tablespace_5_7 ADD DATAFILE ‘/mnt/app01/tablespace_5_7_dbf.ibd’;

Nos comandos acima, apenas criamos a tablespace tablespace_5_7 e o arquivo físico que a define: /mnt/app01/tablespace_5_7_dbf.ibd, veja:

shell> ls -lh
total 185M
-rw-rw—- 1 mysql mysql 56 Mai 11 15:18 auto.cnf
-rw-rw—- 1 mysql mysql 76M Mai 31 06:56 ibdata1
-rw-rw—- 1 mysql mysql 48M Mai 31 06:56 ib_logfile0
-rw-rw—- 1 mysql mysql 48M Mai 11 15:17 ib_logfile1
-rw-r—– 1 mysql mysql 12M Mai 31 06:54 ibtmp1
drwx—— 2 mysql mysql 4,0K Mai 11 15:17 mysql
-rw-rw—- 1 root root 5 Mai 31 06:54 mysqld_safe.pid
srwxrwxrwx 1 mysql mysql 0 Mai 31 06:54 mysql.sock
-rw——- 1 mysql mysql 5 Mai 31 06:54 mysql.sock.lock
drwx—— 2 mysql mysql 4,0K Mai 11 15:17 performance_schema
-rw-r—– 1 mysql mysql 64K Mai 31 06:56 tablespace_5_7_dbf.ibd
drwx—— 2 mysql mysql 4,0K Mai 11 15:17 test
drwx—— 2 mysql mysql 4,0K Mai 11 15:24 world

Agora, vamos criar uma tabela já com dados, e, “joga-la” para dentro da nossa tablespace:

mysql> CREATE TABLE test.City SELECT * FROM world.City;
Query OK, 4079 rows affected (3,51 sec)
Records: 4079 Duplicates: 0 Warnings: 0

shell> ls -lh
total 496K
-rw-r—– 1 mysql mysql 8,6K Mai 31 06:58 City.frm
-rw-r—– 1 mysql mysql 480K Mai 31 06:58 City.ibd

Note que foi criado o City.frm (arquivo de definição da tabela), e, o City.ibd (tablespace da tabela City, que contém dados e índices)

mysql> ALTER TABLE test.City TABLESPACE=tablespace_5_7;
Query OK, 0 rows affected (4,32 sec)
Records: 0 Duplicates: 0 Warnings: 0

shell> ls -lh
total 12K
-rw-r—– 1 mysql mysql 8,6K Mai 31 06:59 City.frm

Ooopsii! Sumiu o .ibd!!! Vamos achá-lo:

shell> ls -lh
total 185M
-rw-rw—- 1 mysql mysql 56 Mai 11 15:18 auto.cnf
-rw-rw—- 1 mysql mysql 76M Mai 31 06:59 ibdata1
-rw-rw—- 1 mysql mysql 48M Mai 31 06:59 ib_logfile0
-rw-rw—- 1 mysql mysql 48M Mai 11 15:17 ib_logfile1
-rw-r—– 1 mysql mysql 12M Mai 31 06:54 ibtmp1
drwx—— 2 mysql mysql 4,0K Mai 11 15:17 mysql
-rw-rw—- 1 root root 5 Mai 31 06:54 mysqld_safe.pid
srwxrwxrwx 1 mysql mysql 0 Mai 31 06:54 mysql.sock
-rw——- 1 mysql mysql 5 Mai 31 06:54 mysql.sock.lock
drwx—— 2 mysql mysql 4,0K Mai 11 15:17 performance_schema
-rw-r—– 1 mysql mysql 464K Mai 31 06:59 tablespace_5_7_dbf.ibd
drwx—— 2 mysql mysql 4,0K Mai 31 06:59 test
drwx—— 2 mysql mysql 4,0K Mai 11 15:24 world

Tchan-ram! Note que agora a nossa tablespace tablespace_5_7_dbf.ibd cresceu, pois, acomoda os dados da tabela City. E, percebam ainda que o .ibd sozinho tinha 480K. Que a tablespace nasceu com 64K, e, acima de tudo, que após jogarmos a tabela para a nossa tablespace, houve uma grande otimização de espaço em disco.

Conclusão

Gostei muito de ver um velho desejo atendido. Nos testes preliminares com tabelas de até 25 milhões de linhas, e, inchando a tablespace até 100 gigas, foi observado um comportamento estável, porém, a grande otimização de espaço observada no inicio não se sustenta com grandes tabelas. Performance, com grande quantidade de acesso à mesma tabela, ganhou a tabela com tablespace exclusiva. Há muito que se testar ainda, contudo, não deixa de ser uma nova feature que possibilitará explorar várias storages em prol da performance.