Joomla! Discussion Forums



It is currently Mon Nov 23, 2009 6:38 pm (All times are UTC )

 





Post new topic Reply to topic  [ 1 post ] 
Author Message
Posted: Thu May 14, 2009 2:50 am 
Joomla! Apprentice
Joomla! Apprentice
Offline

Joined: Mon May 11, 2009 3:19 pm
Posts: 6
Me encontré con un problema y creo que algunos pueden pasar por él. Así que acá les dejo mi experiencia sobre cómo migrar los usuarios cuando son muchos.


El Problema:
Tengo una instalación 1.0.13 que debe pasar a 1.5.10 pero NO quiero pasar todo en forma automática pues estoy replanteando todo el sitio y sus contenidos serán migrados de a poco. Otro problema es que no están ambos sitios sobre el mismo servidor. Así que no puedo hacer una migración “localhost” pues un equipo está en New York y el otro en Los Angeles. Pero mi mayor problema son los usuarios. Al momento de la migración me vi obligado a suspender el registro de nuevos usuarios pues la tasa de crecimiento era bastante alta (unos 50 a 80 nuevos usuarios por día) y el sitio tiene casi 40.000 usuarios activos. Así que la migración de la base debía ser “rápida” y “actualizable”, porque al final deberé inevitáblemente insertar al menos 500 nuevos usuarios pues la migración total me llevará estimo una semana.


El Planteo:
Cuando descargué la extensión mtwMigrator de MatWare me encontré con un resumido panel de opciones muy eficiente para sitios con pocos usuarios (digamos hasta 5.000) lo cual es “mucho para muchos” así que es eficiente para la mayoría. Pero… ¿cómo migro 40.000 sin tener timeouts y “fatal error” por exceso de asignación de memoria?

Mi mayor problema era eso: los procesos superaban en mucho el tiempo prefijado del MySQL y además el manejo de la tabla (en forma de variables) supera la RAM que cualquiera dispone “para alocar” (que no es volverse loco pero lo intenta). Debía encontrar una forma de trabajar “por lotes” o sea poder migrar “pedacitos de mi base” sin superar lo que podía aceptar en cada paso.

Luego me di cuenta de que este procedimiento le puede ser de utilidad no solo a quienes tengan muchos usuarios sino también a quienes tengan que migrar de un servidor a otro y no puedan establecer una relación de confianza entre ambos, y entonces mtwMigrator no puede ver al server remoto y uno recibe u mensaje de “no me puedo conectar a la base” que nos deja pensando en “permisos” y otros problemas.

Así que me uní de las herramientas necesarias y me propuse migrar.


La Solución:
Las herramientas:


PHPMyAdmin (viejo y querido amigo)
mtwMigrator (nuevo amigo)
WinZip, WinRAR (o cualquier otro generador de archivos “zip”)
2 litros de jugo de naranja (o la bebida de vuestra preferencia)
1 martillo (grande)

Si se preguntan para qué es el martillo, es porque los monitores y el teclado a veces tienen la culpa de “mis” errores y deben ser castigados… Pero si quieren pueden prescindir de él.


La Preparación:
En este punto se necesita ser por sobre todo “prolijo”, este proceso lo puede hacer cualquier persona que tenga muy poco de conocimiento del PHPMyAdmin y que sea por sobre todo: prolijo y paciente.

La tarea que tenemos que hacer es la siguiente: Hay que fabricar un montón de “pequeños archivos de exportación” que contengan los datos que iremos “sumando” al destino. Y debemos tener en cuenta que las tablas a migrar son 3:

jos_users
jos_core_aro_groups
jos_core_acl_groups_aro_maps



Con el PHPMyAdmin abren la base original y elijen una de las tres tablas y con esa trabajaremos ahora pero el proceso se repite en las otras:

Tenemos que exportar pequeños “grupos” de no más de 3000 registros. Esto no es difícil. Van a “Exportar”, marcan que quieren exportar un archivo tipo “SQL”, y NO le tildan “Añada DROP TABLE / VIEW / PROCEDURE / FUNCTION” por favor NO le tilden eso porque si lo hacen todo el trabajo no servirá.

Luego abajo donde dice “Volcar” colocan “3000” y en “empezando por la fila” lo dejan en “0” (cero), y le tildan la opción de “Enviar una archivo descargable”… El botón “Continuar” es la opción inevitable y nos encontramos descargando en nuestro PC la primera parte de esa tabla.

IMPORTANTE: una vez descargado el archivo renombrarlo agregándole un número 1 (uno) al nombre … por ejemplo jos_users_1.sql

Una vez finalizado debemos repetir el proceso pero hay un cambio muy importante: debemos cambiar el valor en “empezando por la fila” por el valor usado (o sea 3000), y repetiremos esto hasta terminar toda la tabla… 3000, 6000, 9000, 12000… etc…

O sea que tendremos una serie de “archivitos” de 3000 registros y renombrados como _1, _2, _3 que contendrán los primeros 3000 registros, los de 3000 a 6000 y los de 6000 a 9000 (supongamos que eran 8500 usuarios).

Una vez finalizado esto… debemos elegir otra tabla y repetir todo.

Al final tendremos (ejemplo para 8.500 usuarios):

jos_user_1.sql con datos 3000 usuarios adentro
jos_user_2.sql con datos 3000 usuarios adentro
jos_user_3.sql con datos 2500 usuarios adentro
jos_core_aro_groups_1.sql con datos de 3000 usuarios adentro
jos_core_aro_groups_2.sql con datos 3000 usuarios adentro
jos_core_aro_groups_3.sql con datos 2500 usuarios adentro
jos_core_acl_groups_aro_maps_1.sql con datos 3000 usuarios adentro
jos_core_acl_groups_aro_maps_2.sql con datos 3000 usuarios adentro
jos_core_acl_groups_aro_maps_3.sql con datos 2500 usuarios adentro

¿Mas claro? 8)

Ahora a cada archivo lo zipeamos para que tarde menos en subir y tendremos entonces 9 archivos que serán (ejemplo) jos_user_1.zip, etc, etc… (NO usen formato RAR y solo compriman “normal”)



El Proceso:
Vamos a ver qué haremos con esos archivos: ahora solo tenemos que hacer una base de datos “vacia” en el servidor de destino (o sea donde ya tenemos la base del Joomla 1.5.x)… y dije Una Base y no dije Una Tabla. Vamos a hacer una base sin tablas y la vamos a usar como “donante de órganos”… más bien de “tablas”, para cargar en modo local (localhost) nuestro Joomla! 1.5.x

También usaremos PHPMyAdmin pero esta vez vamos a hacer todo lo contrario… ahora vamos a “Importar

Primero creamos una nueva Base con la herramienta que estemos acostumbrados. Yo usé el cPanel y a mi base la llamé así:

Base: midominio_importar
User: midominio_importar
Pass: importar

¿Poco original no? Pero suficiente para lo que va a durar antes de que la borremos.

Como ya se imaginarán nuestro proceso es “importar uno de los archivos que fabricamos” y luego ejecutar desde el Joomla! El mtwMigrator… la cantidad necesaria de veces hasta restaurar todo sin errores.

Claro que tenemos que prestar atención porque en proceso no es tan sencillo. Cada vez que importamos una porción de tabla luego debemos borrar esa tabla con el PHPMyAdmin para dejar la base nuevamente virgen para esperar otra porción y poder seguir sirviendo de “donante

Cuando hayamos terminado tendremos a todos nuestros usuarios perfectamente migrados a la nueva versión y no habremos sufrido timeouts y errores fatales por pedir demasiada memoria.


Notas Finales:
Les aseguro que escribir la explicación es más tedioso que hacer el trabajo. Solo requiere ser cuidadoso, ser metódico y no equivocarnos… pero ¿Qué sucede si nos equivocamos?

Nada. Si nos equivocamos y por ejemplo nos olvidamos de subir un archivo lo podremos subir luego. En casi 40.000 usuarios cargados en las tablas tuve que reinsertar los últimos y no tuve problemas. Solo recibí por parte del mwtMigrator un mensaje de error cuando encontró registros duplicados. ¡Pero no los duplicó!!!

mwrMigrator no reemplaza los registros duplicados. Si en algún momento nos equivocamos solo tenemos que volver a hacer ese paso y la cantidad de registros grabados será la correcta.




Agradecimientos:
Quiero agradecer a Matías de MatWare porque si su código no hubiera sido liberado como GPL yo no hubiera podido saber cómo trabajaba y no habría logrado migrar casi 40.000 usuarios en poco menos de una hora. Al ser libre ese código me permitió ahorrar muchas horas estudiando las tablas de Joomla! y haciendo experimentos. Gracias a que Matías contribuye con su conocimiento en forma libre (GPL), todos podemos ver el código y entender un poco más cómo trabaja Joomla!

Es un motivo más para que entendamos que importante es el Software Libre


Les dejo abajo del todo la porción de código de mwtMigrator que corresponde a migrar a los usuarios, pero como seguramente ya se dieron cuenta esta idea es apta para todas las tablas de Joomla y en especial para las de contenidos cuando son muy grandes (yo mañana migraré 130-MB de tabla de contenidos). Si quieren migrar otra cosa... van al código fuente del mtwMigrator y se fijan cuales son las tablas que están afectadas a cada uno de los procesos.


Saludos y gracias por perder un buen rato leyendo esta explicación que espero le ayude a alguno a aprender un poco más sobre Joomla!


Horacio Portela
Argentina
info@tx2r.com.ar
http://www.tx2r.com


Code:
function __migrateUsers() {

      //print_r($this);
      //print_r($this->_option);      
      //print_r($this->_externalDB);   

      //$this->_config = $this->getConfig();
      //$this->getConnectToExternalDB($this->_config);

      $query = "SELECT `id`, `name`, `username`, `email`, `password`, `usertype`, `block`,"
            ." `sendEmail`, `gid`, `registerDate`, `lastvisitDate`, `activation`, `params`"
            ." FROM " . $this->_option['prefix'] . "users"
            ." WHERE id != 62";

      //echo $query;

      $this->_externalDB->setQuery( $query );
      $users = $this->_externalDB->loadObjectList();
      //print_r($users);
      $ret = $this->insertObjectList('#__users', $users);

   
      $query = "SELECT aro_id AS id, section_value, value, order_value, name, hidden"
            ." FROM " . $this->_option['prefix'] . "core_acl_aro"
            ." WHERE aro_id != 10";

      $this->_externalDB->setQuery( $query );
      $core_acl_aro = $this->_externalDB->loadObjectList();
      $ret = $this->insertObjectList('#__core_acl_aro', $core_acl_aro);   


      $query = "SELECT group_id , section_value, aro_id"
            ." FROM " . $this->_option['prefix'] . "core_acl_groups_aro_map"
            ." WHERE aro_id != 10";

        $this->_externalDB->setQuery( $query );
        $core_acl_groups_aro_map = $this->_externalDB->loadObjectList();
        $ret = $this->insertObjectList('#__core_acl_groups_aro_map', $core_acl_groups_aro_map);

      return $ret;




Top
  E-mail  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

Quick reply

 



Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group