Friday, April 25, 2014

MySQL Divisórias timestamp - datetime

Original post: http://anothermysqldba.blogspot.com/2014/04/mysql-partitions-timestamp-datetime.html

Então, eu recentemente percebi que eu ainda não falei muito sobre partições MySQL.
Muitos bons posts sobre partições MySQL já existe e eu listei alguns abaixo.
Acontece que se deparar com a seguinte situação e espero que possa ser útil aos outros.

Embora o tipo de dados timestamp é usado frequentemente datetime funciona melhor com partições.
(Timestamp NOT CURRENT_TIMESTAMP PADRÃO NULL ON UPDATE CURRENT_TIMESTAMP)

Assim, o que se lhe segue um exemplo de como a forma de corrigir isso.

Para começar, temos esta tabela simples.

CREATE TABLE `t1` (
`t1_id` int(11) NOT NULL AUTO_INCREMENT,
`field1` varchar(25) DEFAULT NULL,
`field2` int(10) DEFAULT '0',
`time_recorded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`t1_id`),
KEY `tr` (`time_recorded`)
) ENGINE=InnoDB AUTO_INCREMENT=856964


Queremos dividir em campo time_recorded. Para torná-lo dirigir vamos quebrá-lo fora por mês.


ALTER TABLE t1
PARTITION BY RANGE ( TO_DAYS(time_recorded) ) (
PARTITION Jan2014 VALUES LESS THAN (TO_DAYS('2014-02-01')),
PARTITION Feb2014 VALUES LESS THAN (TO_DAYS('2014-03-01')),
PARTITION Mar2014 VALUES LESS THAN (TO_DAYS('2014-04-01')),
PARTITION Apr2014 VALUES LESS THAN (TO_DAYS('2014-05-01')),
PARTITION May2014 VALUES LESS THAN (TO_DAYS('2014-06-01')),
PARTITION Jun2014 VALUES LESS THAN (TO_DAYS('2014-07-01')),
PARTITION Jul2014 VALUES LESS THAN (TO_DAYS('2014-08-01')),
PARTITION Aug2014 VALUES LESS THAN (TO_DAYS('2014-09-01')),
PARTITION Sep2014 VALUES LESS THAN (TO_DAYS('2014-10-01')),
PARTITION Oct2014 VALUES LESS THAN (TO_DAYS('2014-11-01')),
PARTITION Nov2014 VALUES LESS THAN (TO_DAYS('2014-12-01')),
PARTITION Dec2014 VALUES LESS THAN (TO_DAYS('2015-01-01')),
PARTITION Jan2015 VALUES LESS THAN (TO_DAYS('2015-02-01'))
);
ERROR 1486 (HY000): Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed


Então agora o que ....

Bem, eu sei que precisa da chave principal atualizado, se queremos que a partição.

ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (`t1_id`,`time_recorded`), LOCK=NONE;
Query OK, 0 rows affected (38.96 sec)
Records: 0 Duplicates: 0 Warnings: 0

Repare que eu tenho BLOQUEIO = NONE isso é porque eu estou usando o MySQL 5.6
A mudança de chave primária não me permite adicionar as partições, porém, eu ainda preciso ajustar o tipo de dados. Eu estou usando o = FECHADO compartilhou esta época. Por favor, reveja os hiperlinks acima para mais informações. Se acontecer de você escolher um tipo que não funciona, geralmente sugere uma solução viável.

ALTER TABLE t1 CHANGE time_recorded time_recorded datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, LOCK=SHARED;
Query OK, 854312 rows affected (41.89 sec)
Records: 854312 Duplicates: 0 Warnings: 0


Então, agora podemos acrescentar a nossa partição.

ALTER TABLE t1
-> PARTITION BY RANGE ( TO_DAYS(time_recorded) ) (
-> PARTITION Jan2014 VALUES LESS THAN (TO_DAYS('2014-02-01')),
-> PARTITION Feb2014 VALUES LESS THAN (TO_DAYS('2014-03-01')),
-> PARTITION Mar2014 VALUES LESS THAN (TO_DAYS('2014-04-01')),
-> PARTITION Apr2014 VALUES LESS THAN (TO_DAYS('2014-05-01')),
-> PARTITION May2014 VALUES LESS THAN (TO_DAYS('2014-06-01')),
-> PARTITION Jun2014 VALUES LESS THAN (TO_DAYS('2014-07-01')),
-> PARTITION Jul2014 VALUES LESS THAN (TO_DAYS('2014-08-01')),
-> PARTITION Aug2014 VALUES LESS THAN (TO_DAYS('2014-09-01')),
-> PARTITION Sep2014 VALUES LESS THAN (TO_DAYS('2014-10-01')),
-> PARTITION Oct2014 VALUES LESS THAN (TO_DAYS('2014-11-01')),
-> PARTITION Nov2014 VALUES LESS THAN (TO_DAYS('2014-12-01')),
-> PARTITION Dec2014 VALUES LESS THAN (TO_DAYS('2015-01-01')),
-> PARTITION Jan2015 VALUES LESS THAN (TO_DAYS('2015-02-01'))
-> );
Query OK, 854312 rows affected (50.74 sec)
Records: 854312 Duplicates: 0 Warnings: 0


Podemos selecionar, DELETE, UPDATE, INSERT e etc por partição. Mais sobre isso aqui: https://dev.mysql.com/doc/refman/5.6/en/partitioning-selection.html .

SELECT COUNT(t1_id) FROM t1 PARTITION (Jan2014);
+--------------+
| COUNT(t1_id) |
+--------------+
| 661752 |
+--------------+
1 row in set (0.55 sec)
SELECT COUNT(t1_id) FROM t1 PARTITION (Feb2014);
+--------------+
| COUNT(t1_id) |
+--------------+
| 64952 |
+--------------+
1 row in set (0.04 sec)
SELECT COUNT(t1_id) FROM t1 PARTITION (Mar2014);
+--------------+
| COUNT(t1_id) |
+--------------+
| 71336 |
+--------------+
1 row in set (0.04 sec)
SELECT COUNT(t1_id) FROM t1 PARTITION (Apr2014);
+--------------+
| COUNT(t1_id) |
+--------------+
| 56272 |
+--------------+
1 row in set (0.05 sec)


Enquanto isso funciona e nós agora temos uma partição. Também temos agora de considerar a manutenção de partição. blog de ​​Glynn dá um exemplo muito bom de um Dropping automatizada e adicionando de partições. Concedido, se você não quer deixar cair a partição que você terá que ajustar o exemplo.
Eu ajustei-o para o meu exemplo de tabela. Por favor, revise o blog de ​​Glynn para mais detalhes.


DROP PROCEDURE IF EXISTS Rotate_t1_Partition;
DELIMITER ;;
CREATE PROCEDURE Rotate_t1_Partition (newPartValue DATETIME)
BEGIN
-- Setup
DECLARE keepStmt VARCHAR(2000) DEFAULT @stmt;
DECLARE partitionToDrop VARCHAR(64);

-- Find and drop the first partition in the table.
SELECT partition_name
INTO partitionToDrop
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE table_schema='forums_mysql'
AND table_name='t1'
AND partition_ordinal_position=1;
SET @stmt = CONCAT('ALTER TABLE t1 DROP PARTITION ', partitionToDrop);
PREPARE pStmt FROM @stmt;
EXECUTE pStmt;
DEALLOCATE PREPARE pStmt;

-- Add a new partition using the input date for a value limit.
SET @stmt = CONCAT('ALTER TABLE t1 ADD PARTITION (PARTITION ', DATE_FORMAT(newPartValue - interval 1 MONTH, '%b%Y'), ' VALUES LESS THAN (TO_DAYS(\'', DATE_FORMAT(newPartValue, '%Y-%m-%d'),'\')))');
PREPARE pStmt FROM @stmt;
EXECUTE pStmt;
DEALLOCATE PREPARE pStmt;

-- Cleanup
SET @stmt = keepStmt;
END;;
DELIMITER ;


Para que eu possa atualizar esta tabela agora com o seguinte facilmente.

CALL Rotate_t1_Partition('2015-03-01');
Query OK, 0 rows affected (1.11 sec)


Você pode também, como o blog de ​​Glynn aponta, você pode usar isso com um NOW () + intervalo de 1 mês ou sempre que tempo que você decidir por suas partições. Grant você tem que ter em mente que ele irá falhar se você passar uma data que já é uma partição.

Para continuar com a automação você pode adicionar este a um evento.

CREATE EVENT Rotate_t1_Partition
-> ON SCHEDULE EVERY 1 MONTH
-> DISABLE ON SLAVE
-> COMMENT 'Remove oldest partition and add a new one '
-> DO
-> CALL Rotate_t1_Partition(NOW() + interval 1 MONTH);
Query OK, 0 rows affected (0.04 sec)


Tenha em mente uma hora válida para o exemplo acima. Eu apenas usei isso como um exemplo.

Friday, April 18, 2014

Heartbleed garantir & MySQL

Original post: http://anothermysqldba.blogspot.com/2014/04/heartbleed-secure-mysql.html
Bem, um monte de preocupação, e justamente por isso, tem sido feito sobre o bug heartbleed recentemente.

Eu não acho que eu deveria tentar acrescentar muito mais do que aqueles que eu considero especialistas já mencionados. Se você não analisou as seguintes mensagens que deveria.
Tudo se resume a um par de diferentes aspectos.
  • Atualize e garantir o seu sistema operacional pela primeira vez.
    • Se você usar SSL com o MySQL, em seguida,
      • Pare MySQL
      • Criar novas certs para suas conexões.
        • Isso deve incluir novos expiram datas e etc
      • Comece MySQL
Corrigindo o OpenSSL é bastante simples. Você precisa atualizar a openssl-1.0.1e-16 +
É muito provável que seus repositórios de código terá essa atualização, pelo menos é o que eu tenho visto até agora.


# yum list openssl resulted in 1.0.1e-16.el6_5.7


Via Fedora 20, por exemplo,

# rpm -q openssl
openssl-1.0.1e-30.fc20.x86_64

#yum update openssl

Instalada 1:1.0.1 e-37.fc20.1

Assim, os passos são fáceis de seguir, é até você para garantir que seu sistema é seguro.

Monday, April 7, 2014

Instalação WebScaleSQL resolvido ... parte 2

Original post: http://anothermysqldba.blogspot.com/2014/04/webscalesql-installation-solved-part-2.html

Este é um acompanhamento para o: Instalação WebScaleSQL tentou ... parte 1

Então, ser um geek típico, desenvolvedor, idiota ou o que quer .. Eu não conseguiram RTFM ou neste caso o FAQ .

Então, quando eu prestei atenção e não apenas correr para ele, eu instalei WebScaleSQL corretamente.
O maior problema foi que eu estava usando o sistema operacional Linux (Oracle Linux VM), que é muito velho e os repositórios da Oracle fez pouco para ajudar a obtê-lo atualizado. Enquanto eu queria começar com algo que todo mundo pode usar com facilidade, que só não foi isso.

Eu baixei o Fedora 20 . Você pode ver que eles já usam GCC 4.8.2.
Assim, o ponto é bastante simples, se você quiser usar a nova tecnologia, atualize seu sistema operacional também.

Se você realmente deseja atualizar seu GCC e permanecer em seu sistema operacional atual desses hyperlinks pode ser útil:
Abaixo estão os passos que tomou para obtê-lo instalado. Uma vez que as dependências estão no lugar é uma fonte básica de instalação.

#cd /usr/local/
#yum -y install gcc git readline-devel gcc-c++ bison-devel bison cmake ncurses-devel
# gcc -v
gcc version 4.8.2 20131212 (Red Hat 4.8.2-7) (GCC)

#git clone https://github.com/webscalesql/webscalesql-5.6.git
#ln -s webscalesql-5.6 mysql
#groupadd mysql
#useradd -r -g mysql mysql
#cd mysql/
#cmake . -DENABLE_DOWNLOADS=1
-- Successfully downloaded http://googlemock.googlecode.com/files/gmock-1.6.0.zip
-- Configuring done
-- Generating done
-- Build files have been written to: /usr/local/src/webscalesql-5.6

#make
Scanning dependencies of target INFO_BIN
[ 0%] Built target INFO_BIN
Scanning dependencies of target INFO_SRC
[ 0%] Built target INFO_SRC
Scanning dependencies of target abi_check
[ 0%] Built target abi_check
Scanning dependencies of target zlib
[ 1%] Building C object zlib/CMakeFiles/zlib.dir/adler32.co
.....
[100%] Building CXX object mysql-test/lib/My/SafeProcess/CMakeFiles/my_safe_process.dir/safe_process.cc.o
Linking CXX executable my_safe_process
[100%] Built target my_safe_process
#make install
#chmod +x scripts/mysql_install_db
#yum -y install perl-Data-Dumper-Names
#./scripts/mysql_install_db --user=mysql
#chown -R mysql data
#./bin/mysqld_safe &
# ./bin/mysql

mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.6.17 |
+-----------+

mysql> show variables like '%read_only%';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_read_only | OFF |
| read_only | OFF |
| super_read_only | OFF |
| tx_read_only | OFF |
+------------------+-------+

cd mysql-test ; perl mysql-test-run.pl


OK, agora que nós temos que levantar e correr ... podemos explorá-lo ...

Thursday, April 3, 2014

MySQL Explique & SQL_NO_CACHE

Original post: http://anothermysqldba.blogspot.com/2014/04/mysql-explain-sqlnocache.html

Então, hoje eu estava ajudando alguém com o seu desempenho de banco de dados e correu algumas consultas mal escritos. Agora, certamente, todo mundo comete erros, o objetivo é fazer tudo o que puder para evitá-los.

Assim, apenas um par de dicas úteis para fazer antes de deixar uma consulta solto em seu ambiente.

Sempre executar a consulta via explicar primeiro. Algo tão simples como fazer explicar primeiro confirmará sem erros (já que ele não será executado), e permitir que você otimizar a consulta.
Várias ligações já existem sobre como usar explicar:
O objetivo é simples. Você quer chaves válidas nas possible_keys e chaves (não nulos) e quando se trata de key_len você não quer que cada mesa para ser 100s de linhas. Se você pode obter o primeiro key_len a ser 200 (apenas um número que eu escolhi como exemplo), então o seguinte para ser 5,4,3,2,1 e não mais 200, em seguida, sua consulta deve correr bem. Essa é uma afirmação muito simplista e de alto nível e eu sugiro que você revise os links listados para entender Explique mais. A consulta que eu vi hoje tinha 5 + junta e um sub-select (via uma junção foi melhor no onde declaração) e 200 + linhas para cada key_len. Alguns ajustes podem permitir sua consulta a cair entre 200 segundos para 1 segundo ou menos. Sempre, sempre, sempre se explicar.

A próxima dica, tentar testar suas consultas com SQL_NO_CACHE. Isso permite que você teste a consulta real e otimizá-lo da melhor maneira que puder. Uma vez que ela se torna em cache (se ele vai ser), então ele só vai correr muito mais rápido para você.
Uma última nota ... Dê uma olhada nas dicas de desempenho de SQL para MySQL que existiam no local forja, mas agora estão em - https://wikis.oracle.com/pages/viewpage.action?pageId=27263381