viernes, 25 de abril de 2014

Particiones MySQL timestamp - fecha y hora

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

Así que hace poco me di cuenta de que aún no he hablado mucho sobre las particiones de MySQL.
Muchos mensajes de blog en buenas particiones MySQL ya existe y yo hemos enumerado algunos abajo.
Sucede que venir a través del siguiente situación y espero que sea útil a los demás.

Si bien a menudo se utiliza el tipo de datos de marca de tiempo de fecha y hora funciona mejor con particiones.
(Timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)

Así que el siguiente es un ejemplo de cómo la forma de solucionar este problema.

Para empezar tenemos esta sencilla tabla.

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 crear particiones en el campo time_recorded. Para que sea de particular vamos a romperlo a cabo al mes.


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


¿Y ahora qué ....

Bueno, yo sé que tenemos la clave primaria actualizada si queremos que la partición.

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

Tenga en cuenta que tengo LOCK = NONE esto se debe a que estoy usando MySQL 5.6
El cambio de clave principal no permitirá que añada las particiones sin embargo, todavía tengo que ajustar el tipo de datos. Estoy utilizando los = BLOQUEADO COMPARTIDOS este momento. Por favor revise los hipervínculos arriba para obtener más información. Si quieres pasar a recoger un tipo que no funciona, por lo general sugiere una solución viable.

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


Así que ahora podemos añadir nuestra partición.

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 SELECT, DELETE, UPDATE, INSERT y etc por partición. Más sobre esto aquí: 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)


Aunque esto funciona, y nosotros ahora tenemos una partición. Ahora también tenemos que considerar el mantenimiento de la partición. blog de ​​Glynn da un muy buen ejemplo de un goteo automatizado y adición de particiones. Por supuesto, si usted no quiere eliminar la partición que tendrá que ajustar el ejemplo.
He ajustado para mi ejemplo de la tabla. Por favor revise el blog de ​​Glynn para más detalles.


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 ;


Así que puedo actualizar esta tabla ahora con la siguiente sencilla.

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


Puede también, como el blog de ​​Glynn señala, puede utilizar esto con un NOW () + intervalo de 1 mes o cada vez que marco de tiempo que usted decida para sus particiones. Subvención que tiene que tener en cuenta que se producirá un error si se pasa una fecha que ya es una partición.

Para continuar con la automatización se puede añadir esto a un 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)


Tenga en cuenta un tiempo válido para el ejemplo anterior. Acabo de utilizar esto como un ejemplo.

sábado, 19 de abril de 2014

Heartbleed asegurar y MySQL

Original post: http://anothermysqldba.blogspot.com/2014/04/heartbleed-secure-mysql.html
Pues mucha preocupación, y con razón, se ha hecho sobre el bug heartbleed recientemente.

No creo que yo debería tratar de añadir mucho más de los que considero los expertos ya han mencionado. Si usted no ha revisado los siguientes mensajes que deberías.
Todo se reduce a un par de diferentes aspectos.
  • Actualizar y asegurar su sistema operativo primero.
    • Si utiliza SSL con MySQL luego
      • Deje de MySQL
      • Crear nuevos certs para sus conexiones.
        • Esto debería incluir nuevos expirarán fechas y etc
      • Iniciar MySQL
Parches su OpenSSL es bastante sencillo. Es necesario actualizar a openssl-1.0.1e-16 +
Es muy probable que sus repositorios de código tendrán esta actualización, al menos eso es lo que he visto hasta ahora.


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


Vía Fedora 20, por ejemplo,

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

#yum update openssl

Instalado 1:1.0.1 e-37.fc20.1

Así que los pasos son fáciles de seguir, le corresponde a usted para asegurarse de que su sistema es seguro.

lunes, 7 de abril de 2014

Instalación WebScaleSQL resuelto ... parte 2

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

Se trata de un seguimiento de la: Instalación WebScaleSQL intentado ... parte 1

Así que ser un geek típico, desarrollador, idiota o lo que sea .. No pude RTFM o en este caso el FAQ .

Así que una vez me prestó atención y no me acaba de acometer en ella, he instalado WebScaleSQL correctamente.
El mayor problema era que yo estaba usando el sistema operativo Linux (Linux Oracle VM) que es demasiado viejo y los repositorios de Oracle hicieron poco para ayudar a lograr que se actualizó. Mientras yo quería empezar con algo que todo el mundo podía utilizar fácilmente, eso no fue todo.

He descargado Fedora 20 . Usted puede ver que ellos ya usan GCC 4.8.2.
Así que el punto es muy simple, si usted quiere utilizar la nueva tecnología, actualizar su sistema operativo también.

Si usted realmente desea actualizar el GCC y permanecer en su actual sistema operativo de estos hipervínculos pueden ser útiles:
A continuación se presentan los pasos que tomé para obtener instalado. Una vez que las dependencias están en su lugar, es una fuente básica de instalación.

#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


Aceptar ahora que lo tenemos todo listo ... podemos explorarlo ...

viernes, 4 de abril de 2014

MySQL Explicar y SQL_NO_CACHE

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

Así que hoy me estaba ayudando a alguien con su rendimiento de base de datos y corrió a través de algunas consultas mal escritos. Ahora, sin duda todo el mundo comete errores, el objetivo es hacer todo lo posible para evitarlos.

Así que sólo un par de consejos útiles que hacer antes de dejar una consulta suelta a su entorno.

Siempre ejecutar la consulta a través de explicar primero. Algo tan simple como hacer a explicar primero confirmará sin faltas de ortografía (ya que no se ejecutará), y le permitirá optimizar la consulta.
Ya existen varios enlaces sobre cómo utilizar explique:
El objetivo es simple. Usted quiere que las claves válidas en las possible_keys y llaves (no nulas) y cuando se trata de key_len no desea cada tabla sea 100s de filas. Si usted puede conseguir el primer key_len sea 200 (sólo un número que elegí como ejemplo), entonces lo siguiente es 5,4,3,2,1 y no otro 200, entonces su consulta debería funcionar bien. Esa es una afirmación muy simplista y de alto nivel y le sugiero que revise los hipervínculos que figuran entender Explicar más. La consulta que vi hoy tenía 5 + se une y un sub-select (a través de una combinación fue mejor en el dónde declaración) y 200 + filas para cada key_len. A pocos ajustes pueden permitir su consulta a caer a partir de 200 segundos a 1 segundo o menos. Siempre, siempre, siempre explican.

La siguiente pista, trata de poner a prueba sus consultas con SQL_NO_CACHE. Esto le permite probar la consulta real y optimizar de la mejor manera que pueda. Una vez que se convierte en caché (si va a ser), entonces sólo se ejecutará mucho más rápido para usted.
Una última nota ... Echa un vistazo a los consejos de rendimiento de SQL para MySQL que existieron una vez en el sitio fragua, pero ahora están en - https://wikis.oracle.com/pages/viewpage.action?pageId=27263381

martes, 1 de abril de 2014

MySQLUserclone o Sólo tienes que copiar usuarios de MySQL

Original post: http://anothermysqldba.blogspot.com/2014/04/mysqluserclone-or-just-copy-mysql-users.html

 Hace poco me encontré con un mensaje Foro MySQL que estaba buscando la manera de migrar los usuarios a un nuevo sistema.

Si bien esto podría hacerse de varias formas, pensé que me dio la oportunidad de jugar y una demostración de la mysqluserclone herramienta.

Así que tengo dos bases de datos y único usuario una wiki:


root@localhost [(none)]> select VERSION();
+------------+
| VERSION() |
+------------+
| 5.6.10-log |
+------------+
root@localhost [(none)]> show grants for wikiuser@localhost;
+-------------------------------------------------------------------------------------------------------------------+
| Grants for wikiuser@localhost |
+-------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'wikiuser'@'localhost' IDENTIFIED BY PASSWORD '1e09502e61120480' |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, LOCK TABLES ON `wikidb`.* TO 'wikiuser'@'localhost' |
+-------------------------------------------------------------------------------------------------------------------+

select VERSION();
+------------+
| VERSION() |
+------------+
| 5.5.30-log |
+------------+
show grants for wikiuser@localhost;
ERROR 1141 (42000): There is no such grant defined for user 'wikiuser' on host 'localhost'



Así que ahora utilice la herramienta mysqluserclone


Usage: mysqluserclone --source=user:pass@host:port:socket --destination=user:pass@host:port:socket joe@localhost sam:secret1@localhost

# mysqluserclone --source=root:<PASSWORD>@localhost:3306 --destination=root:@localhost:3307 wikiuser@localhost wikiuser@localhost
# Source on localhost: ... connected.
# Destination on localhost: ... connected.
# Cloning 1 users...
# Cloning wikiuser@localhost to user wikiuser@localhost
# ...done.

root@localhost [(none)]> select VERSION();
+------------+
| VERSION() |
+------------+
| 5.5.30-log |
+------------+
1 row in set (0.00 sec)

root@localhost [(none)]> show grants for wikiuser@localhost;
+-------------------------------------------------------------------------------------------------------------------+
| Grants for wikiuser@localhost |
+-------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'wikiuser'@'localhost' |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, LOCK TABLES ON `wikidb`.* TO 'wikiuser'@'localhost' |
+-------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
Tenga en cuenta que le falta una contraseña porque no establece una contraseña para el usuario. Opps que no es lo suficientemente bueno.

Pero reconozco que funciona muy bien si quieres crear nuevas cuentas de usuario con contraseñas nuevas. Que pude pasar la nueva contraseña como parte del comando de clonación

mysqluserclone --source=root:<PASSWORD>@localhost:3306 --destination=root:@localhost:3307 wikiuser@localhost wikiuser:<PASSWORD>@localhost


Pero ¿qué pasa si no sé las contraseñas? Quiero asegurarme de que todos los clientes tienen todos sus mismas contraseñas.

Yo también podría hacer el proceso más adelante.
  • Reunir donaciones de DB 1
  • Edite el archivo de becas Quiero mover
  • Edite el archivo de usuario para agregar comentarios para hacer sql segura
  • Cargue el archivo en DB 2
select CONCAT('SHOW GRANTS FOR `',USER,'`@',HOST,';') as showgrants FROM mysql.user INTO OUTFILE '/tmp/showgrants.sql';

vi /tmp/showgrants.sql

mysql < /tmp/showgrants.sql > /tmp/user_grants.sql

vi /tmp/user_grants.sql
:%s/Grants for/#Grants for/g
:%s/\n/;\r/g
mysql --port=3307 -u root -p < /tmp/user_grants.sql
> show grants for wikiuser@localhost;
+----------------------------------------------------------------------------------------------------------+
| Grants for wikiuser@localhost |
+----------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'wikiuser'@'localhost' IDENTIFIED BY PASSWORD '1e09502e61120480' |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, LOCK TABLES ON `wikidb`.* TO 'wikiuser'@'localhost' |
+----------------------------------------------------------------------------------------------------------+



Ahora tengo el mismo usuario, host y contraseña.