Respaldo automatizado de MySQL con MySQLDump

Generar archivo my.cnf
[client]
user=user
password=secret
routines
databases

Es conveniente cambiar permisos a este archivo con el comano

chmod 600 my.cnf

mysqldump --defaults-extra-file="my.cnf" database1 database2 database3 > database.sql

 

crontab -e
0 0 * * * mysqldump -u mysqluser -h localhost --routines --all-databases | gzip -9  > alldb.sql.gz > /dev/null

 

MySQL Tunning

C:\ProgramData\MySQL\MySQL Server 5.6

Dentro de [mysqld]

innodb_buffer_pool_size=1024M

wait_timeout = 350

Por defecto mysql cierra una conexión después de 8 horas sin recibir ninguna petición del cliente y sin que el cliente sea notificado de las mismas. En una aplicación web puede ser normal abrir un pool de conexiones desde un servidor (Tomcat p.ej) de forma que siempre haya conexiones de sobra sin usar. Esto en la práctica se traduce en que debemos hacer una de dos: - bien reconfigurar mysql (/etc/mysql/my.cnf) para aumentar el wait_timeout - o bien "refrescar" periodicamente las conexiones del pool para resetear el contador interno de timeout de mysql.

Los servidores de aplicaciones suelen tener también parámetros de configuración que nos ayudan: P.ej, Tomcat incluye también un sistema automático de pool de conexiones que en principio soluciona el problema. En la práctica lo minimiza pero aleatoriamente cada 2 o 3 semanas, por experiencia del que escribe estas líneas, vuelve a fallar (Tomcat versión 5).

Por tanto puede ser una buena opción el desabilitar el wait_timeout editando /etc/mysql/my.conf añadiendo la linea wait_timeout=0.
max_allowed_packet = 20M

En algunos casos se desea grabar archivos en MySQL. Por defecto el motor esta configurado para almacenar archivos con un tamaño máximo de 1MB, este valor se encuentra almacenado en la variable max_allowed_packets la cual determina el tamaño máximo de un paquete. El buffer de paquete se inicializa en net_buffer_lenght , pero puede crecer hasta max_allowed_packet cuando se necesita. Por defecto tiene un valor pequeño de 1MB. A partir de la versión 4 de MySQL, se puede incrementar el valor hasta 1 GB. El valor debe ser múltiplo de 1024. Para cambiar el valor solo se debe ejecutar un comando, es algo muy simple. En este caso se asigna un valor de 100MB

mysql> SET GLOBAL  max_allowed_packet=100*1024*1024;
Query OK, 0 rows affected (0.00 sec)

Después de ejecutar el comando si deseas verificar el valor de la variable max_allowed_packet se debe ejecutar el siguiente comando:

mysql> show variables like 'max_allowed_packet';
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 1048576 |
+--------------------+---------+
1 row in set (0.00 sec)

Se debe reiniciar el servicio de MySQL y listo ya puedes almacenar archivos con tamaño máximo de 100MB.
skip-name-resolve

deshabilita la resolución de nombres, por lo que veremos al iniciar MySQL Warnings como los siguientes:

101202 15:43:44 [Warning] 'user' entry '@penny.systemadmin.es' ignored in --skip-name-resolve mode.

Nos esta indicando que no podrá aplicar los GRANTs relacionados con nombres al no poder resolver las IPs de los clientes: deberemos usar la IP en lugar del nombre en los GRANTs.

Al conectarse un cliente, primero va a buscar la inversa de la IP que se ha conectado al resolver, esperará al timeout y luego dejará seguir. En el caso de una aplicación web un tráfico moderado, veremos que se empezarán a colapsar tanto MySQL como Apache ya que se acumularán conexiones esperando el timeout del resolver.

Desactivación de validación de agrupamiento ONLY_FULL_GROUP_BY verificar que exista en el archivo de configuracion la siguiente linea activa:

sql-mode = "STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

Cómo crear, modificar y eliminar un DSN mediante programación

Cómo crear, modificar y eliminar un DSN mediante programación
Por Enrique Martínez Montejo[Microsoft Most Valuable Professional - Visual Basic]
Última revisión: 14/08/2003

El siguiente artículo explica la manera de configurar un origen de datos
con nombre mediante programación, lo que proporcionará una flexibilidad mayor
a la hora de tener acceso a los datos, ya que el usuario no necesitará
explícitamente utilizar el Adminitrador de orígenes de datos ODBC para crear,
configurar, modificar y eliminar un DSN. Para ello utilizaremos la función API
SQLConfigDataSource incluída en la biblioteca de vínculos dinámicos
ODBC32.DLL, cuya declaración es la siguiente:

Private Declare Function SQLConfigDataSource Lib
"ODBCCP32.DLL" ( _

ByVal hwndParent As Long, ByVal fRequest As Long, _

ByVal lpszDriver As String, ByVal lpszAttributes As String)
As Long

Argumentos de la función

hwndParent

Manipulador de la ventana padre. Si el manipulador es nulo, no se
visualizará ningún cuadro de diálogo de configuración. Si por el contrario le
indicamos el valor de la propiedad hWnd de un formulario, se mostrará
el correspondiente cuadro de diálogo de configuración para validar que todos
los datos sean correctos. Si el orígen de datos con nombre ya existe, el cuado
de diálogo nos preguntará si deseamos sobreescribir el DSN ya existente.

fRequest

Tipo de petición. Éste argumento puede contener uno de los siguientes
valores:

Constante Valor Descripción
ODBC_ADD_DSN 1 Añade un nuevo DSN de usuario.
ODBC_CONFIG_DSN 2 Condigura (modifica) un DSN de usuario ya existente.
ODBC_REMOVE_DSN 3 Elimina un DSN de usuario existente.
ODBC_ADD_SYS_DSN 4 Añade un nuevo DSN de sistema.
ODBC_CONFIG_SYS_DSN 5 Modifica un DSN de sistema ya existente
ODBC_REMOVE_SYS_DSN 6 Elimina un DSN de sistema existente.

lpszDriver

La descripción del controlador que se utilizará. Éste es el nombre
presentado a los usuarios en lugar del nombre del controlador físico (archivo
DLL). Entre otros muchos, algunos valores pueden ser:

Microsoft Access Driver (*.mdb) Para bases de datos Microsoft Access.
Microsoft Excel Driver (*.xls) Para archivos de libros de trabajo de Microsoft Excel.
Microsoft Text Driver (*.txt; *.csv) Para archivos de texto con formato de tabla.
SQL Server Para bases de datos Microsoft SQL Server.
Microsoft dBASE Driver (*.dbf) Para archivos de base de datos dBASE.

Para conocer la descripción de los controladores que puede utilizar en su
sistema, revise las subclaves especificadas en la siguiente clave del Registro
de Windows:

HKEY_LOCAL_MACHINESOFTWAREODBCODBCINST.INI

lpszAttributes

Lista de los atributos en forma de "nombre de clave=valor". Estas cadenas
deberán estar separadas por terminaciones Null. Los atributos especificados son
generalmente entradas predeterminadas específicas del controlador, y que se
incluyen en el Registro de Windows. No es necesario proporcionar todas las
entradas, ya que el controlador puede solicitárselas al usuario mediante un
cuadro de diálogo, siempre y cuando que en el parámetro
hwndParent se
haya establecido en Null.

Valor de retorno

La función devolverá 1 si ésta ha terminado correctamente, y 0 en caso de
error. Si al llamar a la función no existe ninguna entrada en el Registro de
Windows, la función devolverá 0.

Crear un DSN de usuario para Microsoft Access

Un origen de datos de usuario ODBC almacena la información de conexión al
proveedor de datos indicado, y sólo es visible y utilizable en el equipo
actual por el usuario indicado. Por cada nuevo orígen de datos de usuario, se
creará una subclave en la siguiente clave del Registro de Windows:

HKEY_CURRENT_USERSoftwareODBCODBC.INI

A continuación vamos a crear un nuevo DSN de usuario, que utilizará el
driver de Microsoft Access para conectarse con el origen de datos:

Dim dl As Long               ' Valor devuelto por la función API

Dim sPath As String          ' Ruta de la base de datos

Dim sAttributes As String    ' Aributos

Dim sDriver As String        ' Nombre del controlador

Dim sDescription As String   ' Descripción del DSN

Dim sDsnName As String       ' Nombre del DSN

Const ODBC_ADD_DSN As Long = 1
' Se creará un DSN de usuario

' Establecemos los atributos necesarios

sDsnName = "Ejemplo_DSN_Usuario"

sDescription = "Nuevo DSN de usuario para Access"

sPath = "C:Mis documentosBd1.mdb"

sDriver = "Microsoft Access Driver (*.mdb)"

' Los pares de cadenas acabarán en valor Null

sAttributes = "DSN=" & sDsnName & Chr(0)

sAttributes = sAttributes & "Description=" & sDescription & Chr(0)

sAttributes = sAttributes & "DBQ=" & sPath & Chr(0)

' Indicamos la ruta del archivo de información de grupos de trabajo

sAttributes = sAttributes & "SystemDB=C:WindowsSystemSystem.mdw" & Chr(0)

' El usuario que inicia sesión por defecto

sAttributes = sAttributes & "UID=Admin" & Chr(0)

' La contraseña del usuario por defecto

sAttributes = sAttributes & "PWD=123456" & Chr(0)

' Creamos el nuevo origen de datos de usuario especificado

dl = SQLConfigDataSource(0&, ODBC_ADD_DSN, sDriver, sAttributes)

If (dl = 1) Then

MsgBox "El DSN de usuario se ha creado correctamente."

Else

MsgBox "No se ha podido crear el DSN de usuario
especificado."

End If

Crear un DSN de sistema para Microsoft SQL Server

Un origen de datos de sistema ODBC almacena información acerca de cómo
conectarse al proveedor de datos indicado. Un origen de datos de sistema es
visible para todos los usuarios de un equipo, incluidos los servicios de NT. A
diferencia del lugar donde se almacena la información del DSN de usuario, por
cada nuevo orígen de datos de sistema se creará una subclave en la siguiente
clave del Registro de Windows:

HKEY_LOCAL_MACHINESOFTWAREODBCODBC.INI

A continuación vamos a crear un nuevo DSN de sistema, que utilizará el
driver de Microsoft SQL Server para conectarse con el origen de datos:

Dim dl As Long                          ' Valor devuelto por la función API

Dim sAttributes As String               ' Aributos

Dim sDriver As String                   ' Nombre del controlador

Dim sDescription As String              ' Descripción del DSN

Dim sDsnName As String
' Nombre del DSN

Const ODBC_ADD_SYS_DSN As Long = 4      ' Se creará un DSN de sistema

Const vbAPINull As Long = 0&            ' Puntero NULL

' Establecemos los atributos necesarios

sDsnName = "Ejemplo_DSN_Sistema"

sDescription = "Nuevo DSN de sistema para SQL Server"

sDriver = "SQL Server"

' Los pares de cadenas acabarán en valor Null

sAttributes = "DSN=" & sDsnName & Chr(0)

sAttributes = sAttributes & "Server=(Local)" & Chr$(0)

sAttributes = sAttributes & "Description=" & sDescription & Chr(0)

sAttributes = sAttributes & "Database=pubs" & Chr(0)

' Si deseamos utilizar la autenticación de Windows NT, deberemos de

' especificarlo en la cadena de atributos

sAttributes = sAttributes & "Trusted_Connection=True" & Chr(0)

' Creamos el nuevo origen de datos de usuario especificado.

' Si deseamos que aparezca el cuadro de diálogo, tendremos que

' especificar la propiedad «hWnd» del formulario donde se realiza

' la llamada a la función API.

dl = SQLConfigDataSource(vbAPINull, ODBC_ADD_SYS_DSN, sDriver, sAttributes)

If (dl) Then

MsgBox "Se ha creado el DSN de sistema."

Else

MsgBox "No se ha podido crear el DSN de sistema."

End If

Modificar un DSN de usuario para Microsoft dBASE Driver

Para que la función API modifique los valores que deseemos, necesariamente
tendremos que indicar el nombre del origen de datos de usuario (o de sistema)
así como el nombre del driver ODBC utilizado. Igualmente, el parámetro
fRequest
deberá de tener el valor de la constante ODBC_CONFIG_DSN (para modificar un
DSN de usuario) o
ODBC_CONFIG_SYS_DSN (para modificar un DSN de sistema).

A continuación vamos a modificar la ruta del directorio por defecto que
tenemos especificado en un DSN de usuario, el cual utiliza el driver ODBC de
Microsoft dBASE:

Dim dl As Long                     ' Valor devuelto por la función API

Dim sAttributes As String          ' Aributos

Dim sDriver As String              ' Nombre del controlador

Dim sDsnName As String
' Nombre del DSN

Const ODBC_CONFIG_DSN As Long = 2  ' Se modificará un
DSN de usuario

' Establecemos los atributos necesarios

sDsnName = "dBASE Files"

sDriver = "Microsoft dBASE Driver (*.dbf)"

' Los pares de cadenas acabarán en valor Null

sAttributes = "DSN=" & sDsnName & Chr(0)

sAttributes = sAttributes & "DefaultDir= C:Mis documentos" & Chr(0)

' Modificamos el origen de datos de usuario especificado

dl = SQLConfigDataSource(0&, ODBC_CONFIG_DSN, sDriver, sAttributes)

If (dl = 1) Then

MsgBox "El DSN de usuario se ha modificado correctamente."

Else

MsgBox "No se ha podido modificar el DSN de usuario
especificado."

End If

Si no se especifica el parámetro DefaultDir, el driver ODBC para
dBASE utilizará el directorio actual del sistema, salvo que en la cadena de
conexión especifiquemos explícitamente dicho parámetro.

Eliminar un DSN de sistema

Para eliminar un nombre de origen con nombre, simplemente deberemos de
especificar el nombre del DSN así como el driver ODBC utilizado. El parámetro
fRequest
deberá de tener el valor de la constante ODBC_REMOVE_DSN (para eliminar un DSN
de usuario) o ODBC_REMOVE_SYS_DSN (para eliminar un DSN de
sistema).

El siguiente ejemplo eliminará definitivamente un DSN de sistema:

Dim dl As Long                 ' Valor devuelto por la función API

Dim sDriver As String          ' Nombre del controlador

Dim sDsnName As String         '
Nombre del DSN

Const ODBC_REMOVE_SYS_DSN As Long = 6    ' Se eliminará un DSN
de sistema

' Establecemos los atributos necesarios

' CUIDADO: no dejar espacios en blanco entre el parámetro

' «DSN», el signo igual y el nombre del DSN (DSN=Nombre DSN)

sDsnName = "DSN=Ejemplo_DSN_Sistema"

sDriver = "SQL Server"

' Modificamos el origen de datos de usuario especificado

dl = SQLConfigDataSource(0&, ODBC_REMOVE_SYS_DSN, sDriver, sDsnName)

If (dl = 1) Then

MsgBox "El DSN de sistema se ha eliminado correctamente."

Else

MsgBox "No se ha podido eliminar el DSN de sistema
especificado."

End If

http://mvp-access.es/softjaen/vb6/api/odbc/sjtodbc002.htm

Extraer parte de un archivo tar

Supongamos que tenemos esta estructura de directorios y archivos:

directorio/
|-- subdirectorio-1
|   |-- archivo-11.txt
|   `-- archivo-12.dat
|-- subdirectorio-2
|   `-- archivo-20.ogg
`-- subdirectorio-3

Hemos creado un archivo TAR que contiene este árbol, y lo hemos guardado con el nombre directorio.tar, Posteriormente queremos mostrar el contenido de ese archivo *.tar, lo hacemos de la siguiente forma:

$ tar tvf directorio.tar
drwxr-xr-x usuario/grupo   0 2008-12-05 16:51 directorio/
drwxr-xr-x usuario/grupo   0 2008-12-05 16:51 directorio/subdirectorio-3/
drwxr-xr-x usuario/grupo   0 2008-12-05 16:52 directorio/subdirectorio-1/
-rw-r--r-- usuario/grupo   0 2008-12-05 16:51 directorio/subdirectorio-1/archivo-11.txt
-rw-r--r-- usuario/grupo   0 2008-12-05 16:51 directorio/subdirectorio-1/archivo-12.dat
drwxr-xr-x usuario/grupo   0 2008-12-05 16:52 directorio/subdirectorio-2/
-rw-r--r-- usuario/grupo   0 2008-12-05 16:52 directorio/subdirectorio-2/archivo-20.ogg

Y finalmente, si lo que queremos realmente es extraer sólo uno de los subdirectorios, haremos lo siguiente:

$ tar xvf directorio.tar directorio/subdirectorio-1
directorio/subdirectorio-1/
directorio/subdirectorio-1/archivo-11.txt
directorio/subdirectorio-1/archivo-12.dat

En este caso hemos extraido un subdirectorio entero, pero podemos extraer archivos concretos, además podemos usar wildcards como * o ? en el comando.

¿Y que pasa con los archivos comprimidos con Gzip o con Bzip2? Pues los comandos son prácticamente los mismos, sólo tenemos que añadir la letra z en caso de *.tar.gz o la letra j en el caso de *.tar.bz2.

Mantenimiento de la base de datos de WordPress

Es conveniente realizar periódicamente tareas de mantenimiento con la base de datos MySQL de WordPress, sobre todo si nuestro sitio tiene mucho movimiento en cuanto a comentarios y recepción/filtrado de spam con Akismet. En su día os recomendé los plugins WP-Optimize y Clean Options, que nos vienen genial para optimizar la base de datos con un click y limpiar registros huérfanos de la tabla wp_options.

En esta entrada me voy a centrar sobre todo en la tabla wp_commentmeta. Esta tabla contiene registros con meta datos de los comentarios, sobre todo información relacionada con el plugin Akismet. Para que os hagáis una idea, en un blog con mucho movimiento de comentarios y también recepción de spam la tabla pesaba nada más y nada menos que 50 megas. Todo ese contenido era completamente prescindible como vamos a ver a continuación.

Lo primero que debemos hacer es un backup de la base de datos antes de tocar nada. Después, con esta primera sentencia SQL vemos el número de registros que podemos eliminar de la tabla:

SELECT * FROM wp_commentmeta WHERE comment_id NOT IN (SELECT comment_id FROM wp_comments)

Básicamente muestra los registros con meta datos de comentarios eliminados, de los cuales se sigue almacenando la información. Cuando nos cercioremos de que efectivamente hacen referencia al plugin Akismet, comentarios eliminados, etc podemos proceder a eliminarlos:

DELETE FROM wp_commentmeta WHERE comment_id NOT IN (SELECT comment_id FROM wp_comments);

Además de esta SQL, podemos ejecuta una que elimine los registros con la meta_key akismet:

SELECT * FROM wp_commentmeta WHERE meta_key LIKE "%akismet%"
DELETE FROM wp_commentmeta WHERE meta_key LIKE '%akismet%';

Después, ejecutad un optimize de la tabla con un mysqlcheck y veréis que se ha reducido su tamaño probablemente en un 99%. Finalmente, habrá que tener en cuenta hacer estas tareas de forma periódica ya que Akismet seguirá escribiendo registros en esa tabla según sigamos recibiendo Spam.

Eliminar cola de mensajes QMail Plesk

En primer lugar comprobamos el número de mensajes en la cola mediante la herramienta qmail-qstat:

# /var/qmail/bin/qmail-qstat
messages in queue: 13221
messages in queue but not yet preprocessed: 64

Para eliminar los mensajes deberemos parar el servicio qmail:

service qmail stop

Una vez el servicio está parado ejecutamos los siguientes comandos en orden. Dependiendo del número de mensajes en cola puede tardar un poco:

find /var/qmail/queue/mess -type f -exec rm {} ;
find /var/qmail/queue/info -type f -exec rm {} ;
find /var/qmail/queue/local -type f -exec rm {} ;
find /var/qmail/queue/intd -type f -exec rm {} ;
find /var/qmail/queue/todo -type f -exec rm {} ;
find /var/qmail/queue/remote -type f -exec rm {} ;

Para acabar volvemos a arrancar el servicio de correo y comprobamos nuevamente la cola para verificar que se hayan eliminado:

service qmail start

Detectar si se está realizando envíos de Spam desde Qmail

Lo primero que tendremos que hacer es conectarnos por consola a nuestro servidor por medio de algún programa SSH como puede ser Putty. Una vez dentro el siguiente paso será consultar las estadísticas de Qmail para ver el número de mensajes que hay en cola. Esto se realiza con el siguiente comando:

/var/qmail/bin/qmail-qstat

El resultado que obtendríamos sería algo parecido a lo siguiente:

# /var/qmail/bin/qmail-qstat

messages in queue: 975

messages in queue but not yet preprocessed: 0

Esto nos indica que tenemos 975 mensajes en cola que aún no han sido procesados. El siguiente paso será ver el listado de todos los que están en la cola pendiente de ser enviados. Esto lo podemos hacer de la siguiente forma:

/var/qmail/bin/qmail-qread

Esto nos mostrará un listado con registros parecidos al ejemplo que os ponemos a continuación:

30 Jan 2013 12:23:36 GMT #69238542 840 <nombre@nombre-dominio.com>

remote nombre@otro-dominio.com

En la cadena anterior, lo más importante es el identificador del mail. Este identificador corresponde al que aparece al lado del símbolo “#”, en nuestro caso 69238542.

Una vez que hemos visto sospechoso este correo, el siguiente paso es localizar la ubicación del mismo. Para ello utilizamos el comando “find”.

find /var/qmail/queue/mess/ -name 162504751

La ejecución de la instrucción anterior nos devolverá la ruta dónde está ese mensaje, en nuestro ejemplo sería:

/var/qmail/queue/mess/22/162504751

En este archivo podremos ver la información correspondiente al mensaje y podremos obtener el ppid del usuario que lo ha enviado. Para ver la información del fichero podemos hacer uso del comando “cat” o “more”.

more /var/qmail/queue/mess/22/162504751

De la información que nos muestra nos quedamos con la parte de la etiqueta “Received”

Received: (qmail 28319 invoked by uid 10007); 30 Jan 2013 12:20:58 +0100

Esa información nos indica que el correo con id 28319 ha sido enviado por el usuario (uid) 10003. Sabiendo el id del usuario es hora de localizar quien está haciendo ese envío, para ello ejecutamos la siguiente instrucción:

cat /etc/passwd | grep 10007

De esta forma sabremos quien ha realizado el envío y podremos tomar las medidas necesarias para solucionar este problema.

Cómo: Crear mediante programación un objeto de conjunto de datos jerárquicos con ADO.NET en Visual Basic .NET

Imports System
Imports System.Data
Imports System.XML

 

Dim myDS As New Data.DataSet("CusOrd")
Dim myCustomers As Data.DataTable = myDS.Tables.Add("Customers")
Dim myOrders As Data.DataTable = myDS.Tables.Add("Orders")
Dim myDr As Data.DataRow

With myCustomers
.Columns.Add("CustomerID", Type.GetType("System.String"))
.Columns.Add("CompanyName", Type.GetType("System.String"))
.Columns.Add("ContactName", Type.GetType("System.String"))
End With

With myOrders
.Columns.Add("OrderID", Type.GetType("System.Int32"))
.Columns.Add("CustomerID", Type.GetType("System.String"))
.Columns.Add("EmployeeID", Type.GetType("System.Int32"))
.Columns.Add("OrderDate", Type.GetType("System.DateTime"))
.Columns.Add("RequiredDate", Type.GetType("System.DateTime"))
End With

myDS.Relations.Add("rel_Customers_Orders", _
myDS.Tables("Customers").Columns("CustomerID"), _
myDS.Tables("Orders").Columns("CustomerID"))

myDr = myCustomers.NewRow()
myDr("CustomerID") = "9876"
myDr("CompanyName") = "Lucerne Publishing"
myDr("ContactName") = "Kim Ralls"

myCustomers.Rows.Add(myDr)

myDr = myOrders.NewRow()
myDr("OrderID") = 6521
myDr("CustomerID") = "9876"
myDr("EmployeeID") = 852
myDr("OrderDate") = #1/5/2002#
myDr("RequiredDate") = #2/1/2002#
myOrders.Rows.Add(myDr)

Console.WriteLine(myDS.GetXml())

http://support2.microsoft.com/kb/316260/es

Fragmento de la última carta de Albert Einstein a su hija

FRAGMENTO DE LA ULTIMA CARTA DE EINSTEIN A SU HIJA

Cuando propuse la teoría de la relatividad, muy pocos me entendieron, y lo que te revelaré ahora para que lo transmitas a la humanidad también chocará con la incomprensión y los perjuicios del mundo.

Te pido aun así, que la custodies todo el tiempo que sea necesario, años, décadas, hasta que la sociedad haya avanzado lo suficiente para acoger lo que te explico a continuación.

Hay una fuerza extremadamente poderosa para la que hasta ahora la ciencia no ha encontrado una explicación formal. Es una fuerza que incluye y gobierna a todas las otras, y que incluso está detrás de cualquier fenómeno que opera en el universo y aún no haya sido identificado por nosotros. Esta fuerza universal es el amor.

Cuando los científicos buscaban una teoría unificada del universo olvidaron la más invisible y poderosa de las fuerzas.

El amor es luz, dado que ilumina a quien lo da y lo recibe. El amor es gravedad, porque hace que unas personas se sientan atraídas por otras. El amor es potencia, porque multiplica lo mejor que tenemos, y permite que la humanidad no se extinga en su ciego egoísmo. El amor revela y desvela. Por amor se vive y se muere. El amor es Dios, y Dios es amor.

Esta fuerza lo explica todo y da sentido en mayúsculas a la vida. Ésta es la variable que hemos obviado durante demasiado tiempo, tal vez porque el amor nos da miedo, ya que es la única energía del universo que el ser humano no ha aprendido a manejar a su antojo.

Para dar visibilidad al amor, he hecho una simple sustitución en mi ecuación más célebre. Si en lugar de E= mc2 aceptamos que la energía para sanar el mundo puede obtenerse a través del amor multiplicado por la velocidad de la luz al cuadrado, llegaremos a la conclusión de que el amor es la fuerza más poderosa que existe, porque no tiene límites.

Tras el fracaso de la humanidad en el uso y control de las otras fuerzas del universo, que se han vuelto contra nosotros, es urgente que nos alimentemos de otra clase de energía. Si queremos que nuestra especie sobreviva, si nos proponemos encontrar un sentido a la vida, si queremos salvar el mundo y cada ser sintiente que en él habita, el amor es la única y la última respuesta.

Quizás aún no estemos preparados para fabricar una bomba de amor, un artefacto lo bastante potente para destruir todo el odio, el egoísmo y la avaricia que asolan el planeta. Sin embargo, cada individuo lleva en su interior un pequeño pero poderoso generador de amor cuya energía espera ser liberada.

Cuando aprendamos a dar y recibir esta energía universal, querida Lieserl, comprobaremos que el amor todo lo vence, todo lo trasciende y todo lo puede, porque el amor es la quintaesencia de la vida.

Lamento profundamente no haberte sabido expresar lo que alberga mi corazón, que ha latido silenciosamente por ti toda mi vida. Tal vez sea demasiado tarde para pedir perdón, pero como el tiempo es relativo, necesito decirte que te quiero y que gracias a ti he llegado a la última respuesta.

Tu padre. ( Albert Einstein)

Cómo cambiar la clave de producto de licencias por volumen en un equipo basado en Windows XP o en Windows Server 2003

1. Haga clic en Inicio y en Ejecutar, escriba regedit y haga clic en Aceptar.
2. En el panel izquierdo, busque la siguiente subclave del Registro y haga clic en ella:
HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsNTCurrent VersionWPAEvents

3. En el panel derecho, haga clic con el botón secundario en OOBETimer y, a continuación, haga clic en Modificar.
4.Cambie al menos un dígito del valor OOBETimer para desactivar Windows.
5. Haga clic en Inicio y en Ejecutar, escriba el comando siguiente y haga clic en Aceptar:
%systemroot%system32oobemsoobe.exe /a

6. Haga clic en Sí, deseo llamar por teléfono a un representante de servicios al cliente para activar Windows y, después, haga clic en Siguiente.
7. Haga clic en Cambiar la clave de producto, escriba la nueva clave del producto en los cuadros Nueva clave y haga clic en Actualizar.

Nota: si vuelve a aparecer la pantalla anterior del Asistente para activación, haga clic en Recordármelo más tarde y reinicie el equipo.
8. Repita los pasos 6 y 7 para comprobar que Windows está iniciado. Cuando reciba el mensaje siguiente, haga clic en Aceptar:
Windows ya está activado. Haga clic en Aceptar para salir.

9. Instale los Service Pack de Windows que desee.

Nota: si no puede reiniciar Windows después de instalar un Service Pack, presione F8 cuando reinicie el equipo, haga clic en Última configuración válida conocida y repita este procedimiento.

http://support.microsoft.com/kb/918342/es